{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 实现简单的线性回归算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 解决绘图中文乱码问题\n",
    "plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签\n",
    "plt.rcParams['axes.unicode_minus']=False  #用来正常显示负号"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备测试数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.array([1., 2., 3., 4., 5.])\n",
    "y = np.array([1., 3., 2., 3., 5.])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 6, 0, 6]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y)\n",
    "plt.axis([0, 6, 0, 6])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 最小二乘法算法实现"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "公式：\n",
    "$\n",
    "a=\\frac{\\sum\\limits_{i=1}^{m}(x_{i}-\\overline{x})(y_{i}-\\overline{y})}{\\sum\\limits_{i=1}^{m}(x_{i}-\\overline{x})^2} \\quad\\quad b=\\overline{y}-a\\overline{x}\n",
    "$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.0"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# x的平均值\n",
    "x_mean = np.mean(x)\n",
    "x_mean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.8"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# y的平均值\n",
    "y_mean = np.mean(y)\n",
    "y_mean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 分子\n",
    "num = 0.0\n",
    "\n",
    "# 分母\n",
    "d = 0.0\n",
    "for x_i, y_i in zip(x, y):\n",
    "    num += (x_i - x_mean) * (y_i - y_mean)\n",
    "    d += (x_i- x_mean) ** 2\n",
    "a = num / d\n",
    "b = y_mean - a * x_mean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.39999999999999947"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_hat = a * x + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y, color='b')\n",
    "plt.plot(x, y_hat, color='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.2"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 如果现在x = 6，尝试预测出y的值\n",
    "x_predict = 6\n",
    "y_predict = a * x_predict + b\n",
    "y_predict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWwAAAD6CAYAAACF131TAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAF9lJREFUeJzt3XtwlOXZx/HvRaVqXjuCEGl1gNCpglQR6Qqt8ipa0IqUIlqUidV6SlUoRW0VjYdqG0BFBlROEbAUI/IiReQoioAiICScD7FiJaDCQNEUJShI7vePO9RCgWzIPvvss/v7zDDJPqy7107gx+X93AdzziEiIqmvTtgFiIhIfBTYIiIRocAWEYkIBbaISEQosEVEIkKBLSISEQpsEZGIUGCLiESEAltEJCKOS+SLNWzY0OXk5CTyJUVE0l5JSck/nXPZ1T0voYGdk5NDcXFxIl9SRCTtmVlZPM/TkIiISEQosEVEIkKBLSISEQpsEZGIUGCLiESEAltEJCIU2CIiEaHAFhGJCAW2iMgxKFpTRM6QHOo8WoecITkUrSkK/D0TutJRRCQTFK0pIm9aHhX7KgAo+1cZedPyAMg9Jzew91WHLSJSQ/lz8/8d1gdU7Ksgf25+oO+rwBYRqaHN/9pco+uJosAWEamhJic3qdH1RFFgi4jUUMFPC8iqm3XQtay6WRT8tCDQ91Vgi4jUUO45uRT+vJCmJzfFMJqe3JTCnxcGesMRwJxzCXuxWCzmtB+2iEjNmFmJcy5W3fPUYYuIRMRRA9vMjjOzzWY2v+rXOckqTESio6gIcnKgTh3/tSj4NSQZqbqFM62ACc65+5JRjIhET1ER5OVBRdW05LIy/xggN9gh3YxT3ZDIj4EuZrbUzMaYmVZGishB8vO/CesDKir8dUms6gJ7GdDROdcWqAt0PvQJZpZnZsVmVrxjx44gahSRFLb5CGtFjnRdjl11gb3aObe16vti4IxDn+CcK3TOxZxzsezsak9pF5E00+QIa0WOdF2OXXWBPd7MzjWzbwHdgFVJqElEIqSgALIOXkNCVpa/LolVXWA/BowHVgKLnXNvBF+SiERJbi4UFkLTpmDmvxYW6oZjELRwRkQkZFo4IyKSZhTYIiIRocAWEYkIBbaISEQosEVEIkKBLSISEQpsEZGIUGCLiESEAltEJCIU2CIiEaHAFhGJCAW2iEhEKLBFRCJCgS0iEhEKbBGRiFBgi4hEhAJbRCQiFNgiIhGhwBYRiQgFtohIRCiwRUQiQoEtIhIRCmwRqT3nYNw46N4dKivDriZtKbBFpHbWrYMOHeDXv4Zt2+Czz8KuKG0psEXk2OzeDf36QevWsHYtjB4NCxdCgwZhV5a2jgu7ABGJoFdfhT59oKwMbroJnngCGjYMu6q0pw5bROJXVga/+IX/ddJJ8PbbMHaswjpJFNgiUr19++Dxx6FlS3jjDd9Rr1gB7duHXVlG0ZCIiBzdW2/BHXfA+vXQrRsMHQpNmoRdVUZShy0ih7djhx+fvvhif4Nx2jSYMkVhHSIFtogcrLISnnsOmjeHF16A++/33XWXLmFXlvE0JCIi31i1yg9/LF7sO+vhw/24taQEddgiAp9/DnffDT/6EWzc6FctzpunsE4x6rBFMplzMHky9O0Ln3wCeXkwYADUrx92ZXIY6rBFMtUHH0DnzvDLX0J2th8GGTlSYZ3CFNgimearr+BPf4Kzz4Z33oEhQ2DZMmjXLuzKpBoaEhHJJHPnwp13wt//Dj16wODBcPrpYVclcVKHLZIJtm2D3Fzo2BH274fZs2HiRIV1xMQV2GbWyMxWBF2MiCTY/v0wbBi0aAEvvwwPPwxr1sDll4ddmRyDeIdEBgEnBlmIiCRYcTHcfjuUlPjOetgwOPPMsKuSWqi2wzazS4HdwLbgyxGRWisvh969oW1b+PhjmDAB5sxRWKeBowa2mX0beAjol5xyROSYOQcvvuiHP0aM8KFdWgrXXQdmYVcnCVDdkEg/YLhzrtyO8AM3szwgD6CJNoURCcd770GvXn4WyPnnw4wZftWipJXqhkQ6Ar3MbD7Q2sxGH/oE51yhcy7mnItlZ2cHUaOIHMmePfDQQ9CqlR+zHj7cL4BRWKelo3bYzrmLDnxvZvOdc7cGX5KIxGXWLD/s8Y9/wPXXw6BB0KhR2FVJgOKeh+2c6xBgHSISr48+gmuu8cvK69b1wyDjxyusM4AWzohExddf+5WJZ53lx6j//Ge/Heqll4ZdmSSJlqaLRMHixX5O9erVvrN+5hn4/vfDrkqSTB22SCr79FO/5ekFF/jvJ0+G6dMV1hlKgS2SipyDv/zFH9M1dizcc48/pqt7d82pzmAaEhFJNevW+WO63n7bd9YjRvhpe5Lx1GGLpIrdu+G++6B1ax/ao0f70FZYSxV12CKpYOpU6NMHNm+Gm26CJ56Ahg3DrkpSjDpskTCVlUHXrtCtG3znO76jHjtWYS2HpcAWCcPevTBwoJ9TPXeu76hXrID27cOuTFKYhkREkm3BAn9M1/r1vrMeOhS0cZrEQR22SLJs3w433ggdOvgbjNOmwZQpCmuJmwJbJGiVlVBY6PepfvFFuP9+31136RJ2ZRIxGhIRCdLKlX5O9ZIlcPHFfvvTli3DrkoiSh22SBA+/xzuusvvS/3BBzBuHMybp7CWWlGHLZJIzvnTyfv2ha1b/T4g/fvDKaeEXZmkAXXYIonywQdwxRXQoweceqrfYW/kSIW1JIwCW6S2vvoKHnsMfvhDWLQIhgyBZcugXbuwK5M0oyERkdp44w0/p/r9931nPXgwnH562FVJmlKHLXIstm6Fnj2hUyc/bW/2bJg4UWEtgVJgi9TE/v3w7LN+TvXf/gaPPAJr18Lll4ddmWQADYmIxKu42B/TVVICHTvCsGFw5plhVyUZRB22SHXKy6FXL2jbFj7+GCZMgDlzFNaSdApskSNxDoqK/PDHyJHQuzeUlsJ11+mYLgmFhkREDqe01HfVb74J558PM2dCmzZhVyUZTh22yH/aswcefNAfy1VS4vf+WLxYYS0pQR22yAEzZ/phjw8/hOuvh0GDoFGjsKsS+Td12CIffQTXXANXXgnHH++HQcaPV1hLylFgS+b6+mu/MrFFC5gxAwoKYNUquOSSsCsTOSwNiUhmWrTI71O9ejV07uwXwzRrFnZVIkelDlsyy86dcNttcOGF8OmnMHkyTJ+usJZIUGBLZnAOnn/eD388/zzccw9s2ADdu2tOtUSGhkQk/a1d64c/Fi6ECy6AESP8tD2RiFGHLelr92647z447zx/6O3o0fD22wpriSx12JKepk6F3/4WtmyBm2+Gxx+Hhg3DrkqkVtRhS3rZtAm6doVu3eDkk31HPWaMwlrSggJb0sPevTBwoD+V/M034cknYflyaN8+7MpEEkZDIhJ9Cxb4Y7rWr4erroKhQ6Fx47CrEkk4ddgSXdu3w403QocOUFEB06b5U2AU1pKm4gpsMzvFzDqZmQYCJXyVlTBqlJ9TPWEC3H8/rFsHXbqEXZlIoKoNbDOrD0wH2gLzzCw78KrSXFER5ORAnTr+a1FR2BVFyMqVfi717bfDuef6vT/694esrLArO4h+xhKEeMawWwF3O+eWVIV3G+C1YMtKX0VFkJfn/w8eoKzMPwbIzQ2vrpT3+efw8MPw9NPQoAH89a9+C9QUXKWon7EExZxz8T3R7CLgz0AX59yuwz0nFou54uLiBJaXfnJy/F/gQzVt6mekySGcg5dfhr59YetW+M1vfEddv37YlR2RfsZSU2ZW4pyLVfe8eMewDbgW+AzYd8jv5ZlZsZkV79ix45iKzSSbN9fsekbbuBGuuAJ69PB7Uy9e7JeVp3BYg37GEpy4Att5vYDVQNdDfq/QORdzzsWyszW8XZ0mTWp2PSN99RU89hicfbbfBnXoUFi6FNq1C7uyuOhnLEGJ56bjfWZ2Q9XDekB5sCWlt4KC/74/lpXlrwvwxhtwzjnwyCN+tWJpKfTpA8dFZ8mAfsYSlHg67ELgV2b2FvAtYE6wJaW33FwoLPTjmWb+a2GhbkaxdSv07AmdOvlx69deg5degtNOC7uyGtPPWIIS903HeOimo9TY/v1+XDo/H7780s+p7tcPTjgh7MpEkibem47R+f9MST/Llvl9qktKfGc9bBiccUbYVYmkLC1Nl+QrL4devfxNxE8+gYkT/RCIwlrkqBTYkjzO+VUlLVrAyJF+v+rSUj9tLwUXwIikGg2JSHKUlvqu+s03oW1bmDkT2rQJuyqRSFGHLcHaswcefNAfy7V8ub/BuGiRwlrkGKjDluDMnAm9e8OHH8KvfuUPFWjUKOyqRCJLHbYk3kcfwdVXw5VXwvHHw7x5frMmhbVIrSiwJXG+/hoGD/Y3FWfO9Js0rVrlDxgQkVrTkIgkxqJFfk716tW+s37mGWjWLOyqRNKKOmypnZ074bbb4MIL4dNP/RFd06YprEUCoMCWY1NZCc8/D82b+6+//z1s2OAPwdWcapFAaEhEam7tWj/8sXCh76xHjPA77IlIoNRhS/x274Z774XzzvPd9Jgx8NZbCmuRJFGHLfGZOtUvJd+yBW65BQYOhIYNw65KJKOow5aj27QJunb1hwnUq+eHQUaPVliLhECBLYe3dy8MGAAtW/r9PwYN8tugXnhh2JWJZCwNich/W7DA31Q8MOtj6FBo3DjsqkQynjps+cb27XDjjX5l4p49MH26n1etsBZJCQps8XOqR43yS8onTIAHHoB16/yKRRFJGRoSyXQrVvjhj3ff9Z318OFw1llhVyUih6EOO1Pt2gV9+0Is5rc/HT/e31xUWIukLHXYmcY5mDQJ7roLtm6F22+HggKoXz/sykSkGuqwM8nGjXDFFXDttfDd78KSJX4IRGEtEgkK7Ezw5Zfw2GNw9tl+G9Snn4alS/3ZiiISGRoSSXevv+4Pv33/fd9ZDx4Mp50WdlUicgzUYaerrVuhZ0+47DI/bj1nDrz0ksJaJMIU2Olm/35/2kuLFjBlCvzxj7BmDXTqFHZlIlJLGhJJJ8uW+Vkfy5f7zvrZZ+GMM8KuSkQSRB12OigvhzvvhHbt/FDIxIkwe7bCWiTNKLCjzDl44QV/TNeoUdCnD5SWQo8eOqZLJA1pSCSqSkt9Vz1vnp+eN3u2PwlGRNKWOuyo2bMHHnwQWrXy+4CMHOnnViusRdKeOuwomTkTevf2e3/ccAM8+SScemrYVYlIkqjDjoItW+Dqq/12pyec4IdBxo1TWItkGAV2Ktu3D556yu+gN2sW9O8PK1f6bVBFJONoSCRVLVrk51SvWQNduvj9P5o1C7sqEQmROuxUs3Mn3HqrP+y2vNyvVnz1VYW1iCiwU0ZlJYwd6+dUjxsHf/gDrF8P3bppTrWIAHEEtpmdbGazzGyOmU0xs28no7CMsmYNXHQR3HKLH69esQKeeAJOOinsyhKmqAhycqBOHf+1qCjsikSiJ54OOxcY7Jy7DNgG/CzYkjLIF1/Avff6OdSlpTBmDCxY4PetTiNFRZCXB2VlfnFmWZl/rNAWqZlqA9s5N9w593rVw2xge7AlZQDn4JVXoGVLP5f6ppvgvffg5pt9C5pm8vOhouLgaxUV/rqIxC/udDCznwD1nXNLDrmeZ2bFZla8Y8eOhBeYdjZtgq5d4aqroF49WLgQnnsOGjQIu7LAbN5cs+sicnhxBbaZnQI8A9x86O855wqdczHnXCw7OzvR9aWPvXthwADfVc+bB4MGQUmJnw2S5po0qdl1ETm8eG46fhuYBNzvnCsLvqQ0NH8+tG4NDzzgD8HdsAHuuQfq1g27sqQoKICsrIOvZWX56yISv3g67FuANkC+mc03s2sDril9bN/u9/y45BJ/EO6MGTB5MjRuHHZlSZWbC4WF0LSpn6HYtKl/nJsbdmUi0WLOuYS9WCwWc8XFxQl7vciqrPTj0v36we7dfk51fv5/t5kiIoCZlTjnYtU9T0vTE23FCr+kfOlS31kPG+bnVouI1FL6zSELy65d8LvfQSzmZ4K88ALMnauwFpGEUYddW87BpEnQty9s2+a764ICqF8/7MpEJM0osGtj40bo1QvmzIE2bfximLZtw65KRNKUhkSOxZdfwqOP+iXkixf7rU+XLlVYi0ig1GHX1Ouv+676/ffhuutg8GD43vfCrkpEMoA67Hh98gn07AmXXeYfz5kDEyYorEUkaRTY1dm/3w95tGjhDxN49FFYvRo6dQq7MhHJMBoSOZply/ysj+XLfWc9bBj84AdhVyUiGUod9uGUl8Odd0K7drB1K0ycCLNnK6xFJFQK7P/knF/w0rw5jBoFffr4gwV69NAxXSISOg2JHFBa6rvqefN8Zz17tj8JRkQkRajDPnD0SatWfh+QkSNh0SKFtYiknMzusGfMgN69/d4fN9zgj+s69dSwqxIROazM7LC3bIGrr4YuXeDEE/0wyLhxCmsRSWmZFdj79sFTT/kd9GbNgv79YeVK6NAh7MpERKqVOUMiixb5OdVr1vjO+umnoVmzsKsSEYlb+nfYO3fCrbf6w27Ly/1qxVdfVViLSOSkb2BXVsLYsX5O9bhx/piu9euhWzfNqRaRSErPIZE1a+COO+Cdd6B9exgxwm+FKiISYenVYX/xBdx7r59DXVoKY8bAggUKaxFJC+nRYTsHU6f6peRbtsAtt8Djj0ODBmFXJiKSMNHvsDdtgq5d4aqroF49WLgQRo9WWItI2oluYO/dCwMGQMuWfuHLoEFQUuJng4iIpKFoDonMn+83atqwAbp3hyFDoHHjsKsSEQlUtDrs7dv9nh+XXOIPwp0xAyZPVliLSEaIRmBXVvr9qZs3h5deggcegLVroXPnsCsTEUma1B8SWbHCz6l+913fWQ8b5vcCERHJMKnbYe/aBX37QiwGH37oT4KZO1dhLSIZK/U6bOdg0iQf1tu2+Q2bCgqgfv2wKxMRCVVqBfbGjdCrF8yZA23awCuvQNu2YVclIpISUmdIZOBAv4R88WK/9enSpQprEZH/kDod9u7dfie9wYPhtNPCrkZEJOWkTmA/+ijUSZ2GX0Qk1aROQiqsRUSOSikpIhIRCmwRkYhQYIuIRERcgW1mjczs7aCKKCqCnBw/jJ2T4x+LiMjBqp0lYmb1gXHA/wRRQFER5OVBRYV/XFbmHwPk5gbxjiIi0RRPh70fuBbYFUQB+fnfhPUBFRX+uoiIfKPawHbO7XLO/etIv29meWZWbGbFO3bsqHEBmzfX7LqISKaq9U1H51yhcy7mnItlZ2fX+L9v0qRm10VEMlXos0QKCiAr6+BrWVn+uoiIfCP0wM7NhcJCaNoUzPzXwkLdcBQROZQ55xL2YrFYzBUXFyfs9UREMoGZlTjnYtU9L/QOW0RE4qPAFhGJCAW2iEhEKLBFRCJCgS0iEhEKbBGRiEjotD4z2wGU1eIlGgL/TFA5UZBpnxcy7zPr86a/RHzmps65apeKJzSwa8vMiuOZi5guMu3zQuZ9Zn3e9JfMz6whERGRiFBgi4hERKoFdmHYBSRZpn1eyLzPrM+b/pL2mVNqDFtERI4s1TpsSWNmdoqZdTKzhmHXIhJFKRPYQR/0m0rM7GQzm2Vmc8xsipl9O+yaglZ1Nuh0oC0wz8xqftpFBFX9uV4Rdh1BM7PjzGyzmc2v+nVO2DUlg5kNN7OfJ+v9UiKwgz7oNwXlAoOdc5cB24CfhVxPMrQC7nbOFQCvAW1CridZBgEnhl1EErQCJjjnOlT9WhN2QUEzs/8Fvuucm5as90yJwCbgg35TjXNuuHPu9aqH2cD2MOtJBufcAufcEjO7CN9lLw67pqCZ2aXAbvw/yunux0AXM1tqZmPM7LiwCwqSmdUFngM2mdkvkvW+KRHY1R30m67M7CdAfefckrBrSQYzM/w/zJ8B+0IuJ1BVw1wPAf3CriVJlgEdnXNtgbpA55DrCdoNwHrgCaCtmf02GW+aEoGdiczsFOAZ4Oawa0kW5/UCVgNdw64nYP2A4c658rALSZLVzrmtVd8XA2eEWUwSnAcUOue2AS8AlyTjTRXYIajqviYB9zvnarP3SmSY2X1mdkPVw3pAugdZR6CXmc0HWpvZ6JDrCdp4MzvXzL4FdANWhV1QwDYC36/6Pkbt9lCKW0rNwzaz+c65DmHXETQzuwPozzd/qEc45yaGWFLgqm4s/x9wPLAW6OVS6Q9fgDLhz7WZnQ28CBjwqnMuP+SSAmVm3wHGAo3wQ0DXOOc+Dvx9M+TvjIhI5GlIREQkIhTYIiIRocAWEYkIBbaISEQosEVEIkKBLSISEQpsEZGI+H8M+rNrae9HvwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 在图上绘制\n",
    "plt.scatter(x, y, color='b')\n",
    "plt.plot(x, y_hat, color='r')\n",
    "plt.scatter(x_predict, y_predict, color='g')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 调用自己封装的py脚本中的最小二乘法进行预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from linearRegression.SimpleLinearRegression1 import SimpleLinearRegression1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "linearRegression1 = SimpleLinearRegression1()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20.1 µs ± 1.41 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n"
     ]
    }
   ],
   "source": [
    "linearRegression1.fit(x, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_predict = np.array([6, 7, 8])\n",
    "y_predict = linearRegression1.predict(x_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 将预测结果绘制在图上\n",
    "plt.scatter(x, y, color='b')\n",
    "plt.plot(x, y_hat, color='r')\n",
    "plt.scatter(x_predict, y_predict, color='g')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用numpy.array的向量化运算提高运算性能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = 1000000\n",
    "big_x = np.random.random(size = m)\n",
    "big_y = big_x * 2.0 + 3.0 + np.random.normal(size = m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "linearRegression1 = SimpleLinearRegression1()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "from linearRegression.SimpleLinearRegression2 import SimpleLinearRegression2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "linearRegression2 = SimpleLinearRegression2()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 s ± 24.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
      "25.5 ms ± 1.16 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit linearRegression1.fit(big_x, big_y)\n",
    "%timeit linearRegression2.fit(big_x, big_y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "根据运行时间可以看出，numpy.array的向量化运算效率比传统的for循环的运算效率快的多"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.9969408272848614"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression1.a_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.0039492414045665"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression1.b_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.9969408272849254"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression2.a_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.0039492414045346"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression2.b_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 衡量回归算法好坏的标准"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn import datasets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 解决绘图中文乱码问题\n",
    "plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签\n",
    "plt.rcParams['axes.unicode_minus']=False  #用来正常显示负号"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 导入波士顿房产数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "boston = datasets.load_boston()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".. _boston_dataset:\n",
      "\n",
      "Boston house prices dataset\n",
      "---------------------------\n",
      "\n",
      "**Data Set Characteristics:**  \n",
      "\n",
      "    :Number of Instances: 506 \n",
      "\n",
      "    :Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.\n",
      "\n",
      "    :Attribute Information (in order):\n",
      "        - CRIM     per capita crime rate by town\n",
      "        - ZN       proportion of residential land zoned for lots over 25,000 sq.ft.\n",
      "        - INDUS    proportion of non-retail business acres per town\n",
      "        - CHAS     Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)\n",
      "        - NOX      nitric oxides concentration (parts per 10 million)\n",
      "        - RM       average number of rooms per dwelling\n",
      "        - AGE      proportion of owner-occupied units built prior to 1940\n",
      "        - DIS      weighted distances to five Boston employment centres\n",
      "        - RAD      index of accessibility to radial highways\n",
      "        - TAX      full-value property-tax rate per $10,000\n",
      "        - PTRATIO  pupil-teacher ratio by town\n",
      "        - B        1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town\n",
      "        - LSTAT    % lower status of the population\n",
      "        - MEDV     Median value of owner-occupied homes in $1000's\n",
      "\n",
      "    :Missing Attribute Values: None\n",
      "\n",
      "    :Creator: Harrison, D. and Rubinfeld, D.L.\n",
      "\n",
      "This is a copy of UCI ML housing dataset.\n",
      "https://archive.ics.uci.edu/ml/machine-learning-databases/housing/\n",
      "\n",
      "\n",
      "This dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.\n",
      "\n",
      "The Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic\n",
      "prices and the demand for clean air', J. Environ. Economics & Management,\n",
      "vol.5, 81-102, 1978.   Used in Belsley, Kuh & Welsch, 'Regression diagnostics\n",
      "...', Wiley, 1980.   N.B. Various transformations are used in the table on\n",
      "pages 244-261 of the latter.\n",
      "\n",
      "The Boston house-price data has been used in many machine learning papers that address regression\n",
      "problems.   \n",
      "     \n",
      ".. topic:: References\n",
      "\n",
      "   - Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.\n",
      "   - Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(boston.DESCR)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',\n",
       "       'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "boston.feature_names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 只使用房间数量这个特征\n",
    "x = boston.data[:, 5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(506,)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = boston.target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(506,)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXEAAAD6CAYAAABXh3cLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJztnX9sHOeZ378PVyN7KQdeCiHcaGvZjpFKiCJTrAlbjuyDpTpW7hz7WP841bBzQK+t0cJIYTcgKiNOJKXCRT3exSkKJKjb3CGIfTnZlo+VqrQyUMmNq56SI00pqloJdzlbCtZnnHLSqrC4tlfk2z+Ws5odzjvzzs7Mzo/9fgBB5HJn5p0h9zvPPM/3fV5RSoEQQkg+GUh7AIQQQrqHIk4IITmGIk4IITmGIk4IITmGIk4IITmGIk4IITmGIk4IITmGIk4IITmGIk4IITlmWdIH+OQnP6luvvnmpA9DCCGFYmZm5ldKqeGg9yUu4jfffDOmp6eTPgwhhBQKETlr8j6mUwghJMdQxAkhJMdQxAkhJMdQxAkhJMdQxAkhJMck7k4h6TI1W8PkoTN4r97AqkoZE1vXYHy0mvawIhHnOfX6+uR17HGPe+f+U6g3mgCAQWsA11gl1OeaKFsDaFxZgFJASQSP33kjdo+vj3R8r20BxHo+uw6cwsW51vlUyhZ2PrSuZ58z8VvZR0SWAfirxX8A8BUAjwL4DQA/U0o9HXSAsbExRYthOkzN1vDc6yfRaM63XytbJXzr4fW5FfI4z6nX1yevY4973BOvnkBzwXxFsU23rsTb5y51dXyvsVslARQ6xhDpfF47geZ85/lYA4LJx0Yi/S5EZEYpNRb0vqB0ym0AfqSUulcpdS+A5QDuBnAHgL8Rkfu6HiFJnMlDZzr+eAGg0ZzH5KEzKY0oOnGeU6+vT17HHve4wwg4ABz9xYWuj+819ua8WjKGSOczv/R8mguqZ5+zIBHfCOBLIvIzEfk+gH8AYJ9qhe+HANzjtZGIPCUi0yIyff78+XhHTIx5r94I9XoeiPOcen198jr2Xoy7G0z2FeZ4cZ9Prz5nQSL+5wDuU0rdAcACUAZQW/zZBQA3eG2klHpRKTWmlBobHg6cNUoSYlWlHOr1PBDnOfX6+uR17L0YdzeY7CvM8eI+n159zoJE/OdKqb9e/HoawAdoCTkAXGewPUmRia1rULZKHa+VrVK7sJNH4jynXl+fvI497nFbAxJqm023ruz6+F5jt0qyZAyRzqe09HysAenZ5yxIhH8oIiMiUgIwDmAFWjlxABgB8G6CYyMRGR+t4lsPr0e1UoYAqFbKuS5qAvGeU6+vT17HHve4Jx8bQaVstV8btAYwNGhBFr+WRU0sieDJjavx8j+7q+vje4198tGRJWO41uouHh0frWLy0REMDV7dV6VsRS5qhiHInfI5AH8MQADsB/B1AG+hFZV/EcAXlVLv+B2A7hRCiI60LLB5cG6ZulN8feJKqf+NlkPFueP7ADwA4N8FCTghhOhwC2mt3sBzr58EgMhCGnRz8HPcZEXETQn9DKGUaiilXlNK/VXwuwkhxJukbJL2zaFWb0Dh6s1harbWfk+RnFssTBJCUiEpITW5ORTJuUURJ4SkQlJCanJzKJJziyJOCEmFpITU5OZQJOcWG2ARQlLBFsy43SkTW9d4Ok/cN4fx0WouRdsNRZwQkhpJCGlSN4esQhEnhMRO2i2QixJlm0ARJ4TESpL+b7IUFjYJIbFSxBbIWYaROCEkFuwUSq1AE2nyAEWcEBIZr14kbvI4kSYPUMQJIZHxSqE4cVv80i58FgmKOCEkMn6pkqpLpFn4jBcWNgkhkdGlSqqVMo5u32LcQZCEhyJOCIlMmCn0vewgODVbw6Y9h3HL9oPYtOdwRyfDosB0CiEkMmFmSa6qlD0dLHEXPvslbUMRJ4TEguksSdPeJlEp0sIPflDECSE9pVe9TYq08IMfFHFCiJakrIC96G3Sq7RN2rCwSQjxxGSZsyj7TrrgWKSFH/ygiBNCPNHllHfuPxVpv0neHJwUaeEHP5hOIYR4ossd1xtNTM3WuhbDXhYc+6ElLSNxQognfrnjZ/Ye7zoN0i8Fx15BESeEeBKUO+42DdKrleb7YaIPQBEnhGgYH61iaNDyfU830+V7UXDsVd49C1DECSFadjy4bonguqnVG6Ei3l4UHPupPwsLm4QQLc6JObrFHgRo/8x0anvSBcd+yrszEieE+DI+WsXR7VvwnW0blkTlAkC53p+FiLdXefcsQBEnhBjhlQZxC7hN2hGvLu++ee1w4YqdTKcQkhOysBqOOw2yac/hTE5t9+rPsnntMPbN1ArX1ZAiTkgOyGpb1V51JOwGrxtOEbsaMp1CSA7IqtsiT1Pbi1rsZCROSA7IsgDlZWp7UbsaMhInJAf0k9siKYra1ZAiTkgOKKoA9ZI8pX7CwHQKITmgV6vhFJ28pH7CYCTiInIDgP+mlBoVke8D+CyAg0qp3YmOjhDSJs8ClAV7ZFExTaf8PoCyiDwMoKSUugvAp0XkM8kNjRBSBPqpGVUaBIq4iGwBcBnA+wDuBfDK4o/eAHC3ZpunRGRaRKbPnz8f01AJIXkkq/bIouAr4iKyHMDXAWxffGkFAPv2eQHADV7bKaVeVEqNKaXGhoeH4xorISSHZNkeWQSCIvHtAL6rlKovfv8BANvTdJ3B9oSQPof2yGQJEuH7ADwtIm8C2ADgQVxNoYwAeDexkRFCCkGc9sh+Wa0nDL7uFKXUr9lfLwr5QwDeEpFVAH4dwMZER0cIyT1x2SOz2j8mbUQpXTNJzQYiQwC+AOAnSqn3g94/NjampqenuxweIYS00HVMrFbKOLp9SwojShYRmVFKjQW9L/RkH6XURVx1qBBCMkrRvNkskHrDwiQhBaSI3mwWSL2hiBNSQIrmzZ6arWHu4ytLXmf/GPZOISR3mKRJipR6cBc0bSplCzsfWpfrFFEcUMQJyQlTszXsOnAKF+ea7dd0Do3ryxbqjeaSfVxftpIfaMx4PVUAwIprlvW9gANMpxCSC+xo1CngNl5pEhHv/ehezzJFeqpIAoo4ITlAF43auAWt7iH2fq9nGRY0/aGIE5IDgqJOt6DpBE4BuZvpyAUx/KGIk74ir9O2/aJOL0HbvFbfeK5Wb+CZvccx+s03cnH+RV2RJy5Cz9gMC2dskqzg5XIoW6VcCEIYh4buvV6UrRIeub2KI6fPF2ZSUFFIbMYmIXnFzzudddEK038kKH/upNGcx8vHzsEO5diPJH8wnUL6hry7HMZHq5jYugarKmW8V29g8tAZz3RI2PNxP4vneVJQP8JInPQNqyplzwZKeXE5mHbx051nGKLe2IrWtyXLMBInfUPWXQ5BRVfTqfRe5xmWKDe2IvZtyTIUcdI3ZNnlYCJ8uui4Vm90iL77PAetgVCTfKLe2IrWtyXrMJ1C+orx0WomRNuNSdG1Mmh5ztgElqZW7H/PT53ES8fO+R5bFvddn2vGkvrIe+0hb1DECckAJsIX5Ab2ctr86Ke/DDy2AvBhcwEvbNsQyw0u77WHvMF0CiEZwGRq+SWPhlZu3DeDecN5IHGmO7JeeygaFHFCMoCJ8JlEsu73lEIkw+NKd2S59lBEmE4hJAOYTOaZ2LrGdyamV7T7+J03BubEbeJMd2S19lBEKOKEZIQg4XMKfa3egMjVPPnQoIUdDy5dIGH3+Hr86ds1XP7Yfwan+wZAn3d+oIgTkiGCxHN8tIrpsxdaU+Ud6e4Pmwvafc4FCDgAXLPsamZ1araGiddOoDnfOkCt3sDEayfaxyfZgiJOSEYwmZE5NVvr6HVi4yxM2pF6SQTzSrX/96PeaLaPtevAqbaA2zTnFXYdOEURzyAsbBKSEUwmyUweOrNEwG1s0bftfbZwh3Wo6LzoutdJujASJyRmus0nm3jF/RwkJRHf7oWCpc2uTMdAsgtFnJAYMW1S5Xy/LfgDmrSH0zWim0gjCI64TeLxVZUyLn90xXOR5UoOF1nuB5hOISRGwvQNcfdL8RJhQecqPV5+cgHw+VtXIuoayLZDZedD62ANdO7NGhDsfGhdxCOQJKCIExIjYfqGmCzeoADsm6lpm1tVK2W8sG0D3v3bhm+kXbZKGBrUR9LOCTnjo1VMPjbScYzJx0ZY1MwoTKcQEiNh+oaY5p/dPVG8/OTP7j3uu49rrQE8cNunsG+mlsvl6YgeijghMbJ57fASC6Cub0iYxRtMVrv329fFuSb2zdR819O08/O1eqOjCMol27IN0ymExMTUbA37ZmodAi4AHrndeybmxNY1xnnsARHfRRVMFoJoNOdx5PR5HN2+Be/seQBHt2/pEHCnPZFLtuUHijghMeGV41YAjpw+7/n+8dEqnti42mjf80r5ro7jzpXr8Irop2Zr+OorJwLz87QfZhOKOCEx4bfyjk58d4+v9y04OnFHw+7l3AC0o+yqQWtbex/PvX7SaEIQ+4FnE4o4ITHhJ3JeUbQtwmFmQto3iqDl3Ex7eps4ZHTbkmxAESckJvzy0l5RtDMHbYp9o9D50XcdOIVNew7j2b3Hcc2yAQwNWr49vf1SJHZahv3As42RO0VEVgK4HcCsUupXyQ6JkHxii9wzGrufnVYZH61i5/5TRhGwE2c0rBPfi3PNdmRfbzRRtkq+y67pXC0lEfzBb9EbngcCI3ERGQLwXwDcAeCIiAyLyPdF5M9E5PnER0hIzvBbTee510/i+amTntPabby2XrH8qp97araGAcMVe4JcJbq0CwU8P5hE4rcB+FdKqWOLgr4FQEkpdZeI/KGIfEYp9RfJDpOQ+EhqwQOTImGjOe+7eLGubezcx/OYPnsBO/ef8r0BeOGXMjFZUYhkm0ARV0r9DwAQkV9DKxpfCeCVxR+/AeBuAB0iLiJPAXgKAFavNrNQEdILwjaoCoNpkdBP5HU/U4BnH3Gbkgg+ce0yT4EPcpVwKbV8Y1TYFBEBsA3ARbT+nuwy+wUAN7jfr5R6USk1ppQaGx4edv+YkNQI06DKBKfNz7RIqUu3DA1aWmsg4N+FcF4piGBJ4yq6SoqPkYirFk8D+DmAzwOw/9KuM90HIVkgTIOqINw2PxOskmDjp4c8f/bAbZ8KNYvTzcW5JiCtlrFcZb5/MCls/msR+e3FbysA9qCVQgGAEQDvJjM0QuJHl1oIM5HFjr6f2Xs8tMOkOa9w9BcXPH925PT59ixOt5CbCntzXqHeaDK33UeYRNEvAviyiPwEQAnA1OL33wbwWwAOJjg+QmLFdBKMjm793SbYTwO7x9fjiY2r22mXkgg+f+vKwN4oTtyTf0hxMSlsXgTwBedrInLv4mu/p5S6lMzQCImfbt0Yzg5/SWE/DTw/dbKjiDmvFN4+d2lJB8K5j6/4zvZ0t7AlxaSrVrSLwv5K4BsJ8SApi58pYd0YbkeLH1ZJsGK5t0skaLuJrWt8V7O3OxCGGRebVhUf9hMnPSVJi19SmFoHq64b0s3bQ2Qa1dVj6YqkbkF2PlXonhDYtKr4ZFbE047WSDL4Wfyy+vsNimbjWB2nuaDaf+86Kh7dDu2nCq+onPbC/iCT9sCgDm0kv8Rp8esVftFsnDa+Wr2B631WlP/gwyvG/cRpL+wfMhmJ5zFaI2aEWYMySdxPepvXDmuXLZvYusYzyvUSSed+dVPodZRE4NcSxY7WdZ8BzrzsTzIZiecxWiNmRLX4xYHXk95Lx85pn/xMo1z3fr0E3M8mOK8U6gG9xfkZIG4yGYlnJVoj8ZOFhksmhUqTFebD7rck0rYJ6gqRQXG7QqtgWilb2PnQOkbeJJuReBaiNVJcTKNZ0/fZMziDPOTzSmHfTA2b1w6HmrjjRb3RxMSrJ1gnItkUcRZpiksWitamT3Qm7ws7g9P2ez9ye9W377iN33vsHDnpbzKZTgFYpCkqWShaexUq3Zg++Zl6yJ3U6g3sm6kFFj3f3fMAAOCW7QeNveOk/8hkJE6KSxaK1l5Pek9uXN3Vk5/fuHVRdEkkUPid2/o9EbBORDIbiZNikpWidVxPerrzsWdvelkTTSL3x++8sf31xNY1mHjtBJrznfG4NSCsExGKOOktOmHrtRiF8Yn74Xc+OieO3zT5kggev/NG7B5f337N3s+uA6faDa/oTiE2FHHSU9KyGDpFuzJo4dJcEwuLP7N94nB879XPZWq25imk33p4fcfr1yzzz1LqcvJ+wuz35MAWFf2NqBAzyrphbGxMTU9PJ3oMQvyELEwXQjd2WmT67IUOoXey6daVePvcpY79C1qebvt/G3umJ9AZWXv93ESYdT1T6ObKPyIyo5QaC3wfRZzkGXd0bOMUMhMPdy+plC0c33G/dlyVsoWPriwYCbNuH9VKuaNtLckfpiLOdArJLX4RdqM5j537T2H67IVMCTjQmqgzNVvTOlu8epHrbJhZcPuQdKHFkOSWII92vdHUpkDSZvLQmdCOHC9hjmPNUJJvGImT3NGLpdKSplZvYGjQgjUgaC5cTWmWrRKutQY8l12zhdldpPXaB62H/QNFnMRCrxwSUYqUWcMt1LY7BYDWtug+f3sfg9YAGs0FulP6EIo4iUwvl1zrZpp7XvjoSsv06GfD3LTnsKYGsIAXtm2gePchhRdxemiTx7Qfiu53EeZ3VOSCnfOa6XzhuvNXABdN6VMKLeJ5XJQ3j5g4JHS/i+mzF7Bvpmb8O7q+bIVeST5PBN2kdNP8TbYlxaTQ7hS/CJHEh4lDYuf+U56/ix/99JfGv6Op2RoufVhcAQeCXSUTW9dA15yWjpT+pNCROD20vSGoH8rUbE0bPevasb5Xb3S4UAYEWEh2XlrqmLhKxkermD57AS8fO7dkJigdKf1JoSNxemh7Q9AiHn5PPrp2rZVBq2OxhaILeEnEeKr87vH1eGHbBi6aQgAUfNo9+0pkA79FDZ7cuLojJw60fkfXLBsodO7bi2qlHKnoS4oFp90jG4vypk0WREBXjBsatLB7fD3GblrZTpvYCyZ026wqrxOABGiPvduiL8kGvf7MFToS73ey8iRiMo60J/EMWgMQEVz+ONrxv7NtA776yonApdecuDsd2pREPPfD5lbZJc7PnGkkXuiceL+TFXeOycLXaU/imWsuRBZwoHWufgLutRSc7t1+RV+STdL4zBU6ndLvZMmdE7QcWhGEaWjQAqBP6+giaF07WV0kzsJ8dknjM8dIvMAk7c6Zmq1h057DuGX7QWzacxhTs7Wutx/QuFTyglUS7Hiw1fdkYusalK1Sx8/LVgmb1w57Xi/d+x+/80bP12klzC5pOOIo4gVGJw5xiICd+6vVG1C4WnQzFXL39mFyyFmjJILJR0faTxpe6aNHbq9i30zN83rp0k27x9cHpqFItkjyM6eDhc2Ck1SlPOqKMn4phAWlUBm0oBRwqdH0nWqeNtaAYPKxkcBryhV4+oe4PnO0GBIAwbnobtHl+Gr1BjbtORz4B6zbfkEpvLPngfb39gciC4i02sV6rTgf9MHNUn2CJEtSnzkdgSIuItcD+BMAJQCXAWwD8D0AnwVwUCm1O9ERkkxSGbQ8Fy7w8jsDS33Nuuh6QAS3bD+IyqCFyx9dwcfz2UmzKAXMfuP+Ja+bNFrTnS+LlCQqJjnxJwB8Wyl1P4D3AfwjACWl1F0APi0in0lygCR7TM3W8MGHVzx/5pZcnb3KK3cItHLjCq3FDrIk4EAr9eHELsw+s/d4oK0sjVwp6Q8CI3Gl1Hcd3w4DeBLAdxa/fwPA3QD+Iv6hkawyeehMx3JgQXilDNyzaQc0drossXntcPtrk8lJzvPm7GGSFMY5cRG5C8AQgHcB2BaECwD+vsd7nwLwFACsXr068iBJtgibx3WnDNz54yc2rs7sgsZO9v7slxi7aSXGR6tGk5Pc593rXCnpD4wshiKyEsC/B/A7AD4AYP91Xue1D6XUi0qpMaXU2PDwsPvHJOeEyeO6UwZe1sQ8CDgANBdUO0US5JZhqoT0ikARF5HlAF4F8JxS6iyAGbRSKAAwglZkTvoIXT7bTRan10fF7nPuNzWJfm7SS0zSKf8ErZTJ10TkawD+CMCXRWQVgF8HsDHB8ZEMYovTzv2nfNvFevmf826pGxDBM3uPe/5MAC5WTHpOYCSulPqeUmpIKXXv4r8fALgXwDEAm5VSl5IeJMke46NVHN9xPwYt7z8hu4+Im7xb6vyKr/ZixWHbDxASha6m3SulLiqlXlFKvR/3gEi++N2Hb4NV6kwuOPuIuHE6PLJA3H0nwrYfICQqnLGZMbKwiEMYwlrnjpw+38vh+VIpWxCB56SlKNge8Sz/3khxoIhnCJOZf70aR5gbSRjrXJZy4pcaTW0v76hk6TzDkrdAot9hF8MMkYVFHKJ2Jwzad5ZIcmpRXnP/Sf7+STJQxDNEFpokJXUjmZqt4auvnkhUOLOCl0c8au/1XpGFQIKEgyKeIdJoKO8mqRvJ5KEzmA8xVd/GGhCsWB7sSY+bStlaUrD1Qxb/eXnE8xTdZiGQIOGgiGeILDRJSupG0o0ICIA7bhlCZXB5pGOHpVop4/iO+zH56MiSplc6FFqdHb3yx3mKbrMQSJBwUMQzhMmCwkmT1I2kGxFQAP7XLy70dEEI57mOj1ZxdPsWfGfbBt8ZmjYX55p4du9x3OxKmeQpus1CIEHCwZV9SBvblVCrN9qL9FZjcifYOfFuUipJMzRooT7X9HVi3Lz9YOj9lq0SvvXw+vY19SKu6xsndKdkA67sQwCYfyDd9sZ5pdoRWBwfYHsfX/vTk7j8cTK9UwatAcw1F0Jt47U8mtc1061g74edMpnYukbbtjYtG6kf7LaYL5hOKTBhCmq9yNuOj1Zx6ptfNEpNmDA0aLXTTk9uXI2hFdeE2l7nIvG6ZpvXDnc17vfqjY40mRdZzY+TfEARLzBhhDnOvG2Qne76sndflTBUK2XseHBde9mzl4+dC4yUK2WrLaQlkfa1cI5Pd82OnD6PJzaG741v1wLs/LruRpDF/DjJBxTxAhNGmONyJQRF/89PnfTtfGhC2Sph89rh9nGA4Ik7ZauEnQ+taxfu7EZW7vH5XbPd4+tDj9Md6dP9QeKGIl5gdMIwILIkOo7LlbBz/ylt9D81W8PLEReAsB07R06fN+pL7nb57DqgHx8QLLJBlkM70nY7i+ynk1q9sSQap/uDRIGFzQKjK6jNK7WkmBbHGpBTszVtlP1evYHJQ2cizdgUXO1R/qymp7cTd9FyarambXZlR+ATW9dg4tUTS9YQrdUbuPW5H2NeKQj0kb/SHNf5e3Bve82y9GIpOlHyD0W8wNgfxq++cmJJH2yvTntRXQl+xblVlXLkvK8zl74qwC1ip1w27TncFqjLH13xHV8bTeLavoZq8S06IXefZ9BqRvVGM7VGZ1louEaiwXRKAXEWFicPndEuZBB3Mc1vfxNb10TO+9YbzXah1Cv940xlPHJ7Fftmah25eb9c/NzHV9pRaXM++HlBoVUc9cJ9nibXOQ2HSp5mkhI9FPGC4VVY1DkiKprVd7o55qY9h7WR6dCghfHRqvHanH44o0X37NYXtm3Ad7ZtAAC8dOxcqLU8L841OwqlJtipFSdhiplueu1QydNMUqKH6ZSC4RVd6cT1gw9b0WeUR2f3I7mbslVqr/LjzLvbN5ducuR2tHh0+xbPRlPdLsTcaM63Z6qa4kytOG2LwNXz9Zvs42RVpdzTHLUuJUWnTL5gJB5AXlqI2oSJJJsLKvKjs1++d2jQWtL7xY7ISyKRipxe0WJQ7tkEe6ZqGGwh19kWx0ereOT2ajv9IgBKA50xvNs22Ytuh+yTUgwo4j7kqYUo0Bpv2FmFUR+d/bb/0DUFfmq2hg273sAze4/7RruC1sQc3WLLgHe0GEejrAGB7+xKHe6zcUbkU7M17JupdRRGB9A541Rnm0wyR52FhmskOkyn+OBX+MniH7rOwidoOTu8CntRH539XCLOa2Wa6giy5wGt86nVG9i05zA2rx3GkdPnY+t0uKCuunR0xzZ9gniv3mg1/vJwBzUXFJS66trZdeBUoP0xCdgnJf8wEvchb4Uf3bgUgJ0PrYv06KxLKwWtXm+PySTV4RRnZyrCGRk7RbRWb+Alg+n23eI+tp0CMn3aqQxaeO71k9qnjnqj2X7K81usmTlq4gdF3Ie8TZHWjataKUd6dPZLKwWtXm+PyeTG5xRnd0756PYtqFbKiS/vVnH1dXG6apzpkCDKVglKIXKOnjlqEgRF3Ie8FX6CxmuL4Tt7Hlji7PDDL63kJ87OY4e98TWa89h14FTHa714AnJ60W3CFkztG+SliD1iADBHTQKhiPuQt8JPUuP1SyvpxLkk0nHsbjziF+eaHWIa9kZglWRJZG2CaVMsL+zWAOOjVd9r41e0tbGfoAjxg4XNAPJW+ElivH5+Yi8PtL2ijV0ctCP2yqCFa5YNhOpi6CwiT2xdg2f3HjdOqaxYvqzVudCjF4oTr2KlsygbNMXfiVO4/a4NgEB/fVaf+Ei2YCROAtFNcd+8dtg3+nfn0i/ONfHRlXAr7zij4PHRaqic+KVGE+OjVUw+NtIRkQ9aAx32vqAeKBNb1xgVM93C63dt3D8bGrRQKVu5eOIj2YJrbAaQty5vSY33+amTePnYuQ7Bc0bcXtitV6PgthyG2WdJBAtKBS5L52UBdB87aI3NStnCzofWZfpvg+QL0zU2GYn7kMfJPkmN98jp854ph10HTmlntIbJJVslgeUxi9GdUvB6KrAGBFZpaaw8r5TvdbCvl5eAu4+ta3ZlE/YJg5C4oIj7kLcub0mOVyfIF+ea2puGaSGyWilj8tERTD42EliU9UpRTD42gslHr27rJbhe10HnOnEXZQEE9lPJ8t8FKTYsbPpQlMk+cYzXtLjnLAhObF2DiddO+LZ2dS70AJj1sdYVb+3XbtGkPtzXQXddFpRasn+T1e6z+ndBig0jcR+KMtknjvGGsQjaYjY+WsWK5f5xQpixmTYjM70Oula8XtubnH9l0MpVszRSDCjiPhRtsk8UvNIYOg+2UwT9JryEnfZvmu83uQ5TszXt2LxaCXhN/3dilQQffHglN/UTUhyYTvEhjnWjX7iLAAAIKElEQVQnu6Fbh0mvx/ulkU9h30xtiQ/aKZa6NIxX3lmHzkGia0Zmch0mD52BzjquayXgTOO4f0eXP7qyxP+eRLO0vLmlSPLQYpgxvDrnBVn5nNsm9QHXjeuR26s4cvq89phRzke3vRMB8M6eB0Kfzy3bD/p6zt8NuU/d/rodnxdRryXJF7FaDEXkBhF5a/FrS0QOiMhREfmdqAMlnXTrMEnaDqkb15HT5337sURtBRDUt6TbfL/fdgKEvm69qJ/kzS1FekOgiIvIEIAfAFix+NJXAMwopTYBeFREPpHg+PqObh0mph/wblcqiuJ86bbxVtD+Beg63z+xdY2ntxxoTcEPK4y9qJ/kzS1FeoNJTnwewDYA/3nx+3sBbF/8+icAxgAciX1kfUq36x6afMDdj+PORYeDhDWt9Rj9rI0KZpZEL+ztntl73PPn7uvplaoCOvPuQamlqHBNTOJFYCSulPp/SqlLjpdWALDDtwsAbnBvIyJPici0iEyfP+/fb5p00m1EZ/I4H+VxPC2njl/fkrBLqLkZH61q9+G8bl6pqolXT2DitRMdr+2bqWFi65qunjhMyJtbivSGbiyGHwCw/8Kv89qHUupFpdSYUmpseNh/5RfSSbc5ZJMPeNSUSBptecdHq3hi4+olQh6XeJlcN6+bX3NBLZnElHR+Om+tkUlv6MZiOAPgbgCvARgBcCzWERWAqC6RbtrJmtjqoj6Op9WWd/f4eozdtFJ7blGut8l1C5NzTjo/nbfWyCR5uhHxHwD4sYjcA+CzAH4a75DyTZS8c1SCPuC6/tZJP46HFVnd+3VdCMNeb6/9O6f+u+m2nzghvcBYxJVS9y7+f1ZEvoBWNP4NpVS0RQQLhl/eOe0IKs7JQKbCHFZkTd9vH99LXP2udzei73XzswYEEHSkVOK4IXIyDwlLVzM2lVLvAXgl5rEUgqzbwLxmHT6793gowQgjhGFvaibvD5oABOivdzc3Wd3Nz+u1KIKb5lMcyS+cdh8zebGBRRGMMEIY9qZm8rrJwsW6693tTTaoc2IcZPkpjmQXNsCKmbzYwKLYDcMIYdiZjCavmzzV6K53ljtTZv0pjmQTinjMZNUG5p6pqSvUmQhGGCEMe1MzeX+Q4A4NWr757azdZO3fja6XSxZuMCS7MJ2SAFmzgXmlTrxWeAf0guEsuF1ftmCVxKioF7aYavJ+r0Kjcxw7Hlznue9uxmMyUzNKLjwov5/2DYZkH3YxTIleuhB0kbdbyHUd8byExhoQXHftMtTnmlhVKWPz2uFEp5y7cbpTSiKYVwrVHnRu1LlSun3a8nsqivt8SL4w7WLISDwFeu1C0KVIFFpCESS8uhmLg8uXYfYb96fiqujF047uvN1EKT7qfjfuZesI0UERT4FeuxB0jplqpWwkFEEFt6K6KnoxUzMvbiaSXVjYTIFeuxCiFvOCCpm9Op9u2+h2Sxgh7VZ0s1hoJfmCIp4Cvba5RXXMBAlNL84n6UUvvPA6b2tAlvQhjyK6WXUzkfzAwmYK5HGZLb9CbC/OR1cANE0JdUvS7hRCdLCwmWHSWoA5Cn6FxF6cj+miF3GPoRczNQmJAkU8JbLmJY9K0ucTVABk3xHSrzAnTnJBUF6eiwiTfoWROImVblIaJtsEpWzYd4T0KxRxEhvdLtBguo1fyoZ+a9KvMJ1CYqOblEZcaRD6rUm/wkicxEY3KY240iB5dPwQEgcUcRIb3aQ04kyDFM3xQ4gJTKeQ2OgmpcE0CCHRYCROYqOblAbTIIREg9PuCSEkg5hOu2c6hRBCcgxFnBBCcgxFnBBCcgxFnBBCcgxFnBBCckzi7hQROQ/gbKIHiYdPAvhV2oPoATzPYsHzLBbO87xJKTUctEHiIp4XRGTaxM6Td3iexYLnWSy6OU+mUwghJMdQxAkhJMdQxK/yYtoD6BE8z2LB8ywWoc+TOXFCCMkxjMQJISTHUMQBiMgNIjKb9jiSQkSWicg5EXlz8d/6tMeUNCLyXRF5MO1xJIWI/AvH7/O4iPyHtMeUBCIyJCI/FpHpop4jAIjILSJyUETeEpE/CLMtRbzF7wMo8mKMtwH4kVLq3sV/J9MeUJKIyD0A/o5S6kDaY0kKpdT37N8ngLcA/MeUh5QUXwbw8qLt7hMiUlSb4b8F8G+UUvcA+Lsicq/phn0v4iKyBcBlAO+nPZYE2QjgSyLyMxH5vogUto+8iFhoCdq7IvKbaY8naUSkCuAGpVRR+z3/LYDPiUgFwI0AfpnyeJLi7wF4e/HrvwFwvemGfS3iIrIcwNcBbE97LAnz5wDuU0rdAcAC8BspjydJfhvA/wHwewDuEJGvpDyepHkawPfSHkSC/E8ANwH4lwD+L4AL6Q4nMV4DsGMxBfhFAP/ddMO+FnG0xPu7Sql62gNJmJ8rpf568etpAJ9JczAJMwrgRaXU+wBeArA55fEkhogMoHV+b6Y8lCTZAeCfK6W+CeA0gH+c8ngSQSm1G8B/BfBPAfxAKfWB6bb9LuL3AXhaRN4EsEFE/lPK40mKH4rIiIiUAIwDOJH2gBLkLwF8evHrMeSjb0+33APgp6rYPuEhAOsX/3bvBFDkcz0OYDWAb4fZiD7xRUTkzcUiUeEQkc8B+GMAAmC/UuprKQ8pMUTkEwD+EMANaKWOHlVK1dIdVTKIyO8CmFZKvZ72WJJCRO4A8EdopVT+DMA/DBOl5gkR2QXgL5VSPwy1HUWcEELyS7+nUwghJNdQxAkhJMdQxAkhJMdQxAkhJMdQxAkhJMdQxAkhJMdQxAkhJMf8fxhRZK0+IUTsAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 过滤掉一些错误的最大值点\n",
    "x = x[y < 50.0]\n",
    "y = y[y < 50.0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用简单线性回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from common.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_train, x_test, y_train, y_test = train_test_split(x, y, seed = 666)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(392,)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(98,)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 7.2, 20.8, 33.2, 13.1, 39.8, 16.5, 14.9, 14.5, 26.5, 19.1])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "from linearRegression.SimpleLinearRegression2 import SimpleLinearRegression2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "linearRegression2 = SimpleLinearRegression2()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SimpleLinearRegression1()"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression2.fit(x_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7.8608543562689555"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression2.a_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-27.459342806705543"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression2.b_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在图上绘制出预测结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXEAAAD6CAYAAABXh3cLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJztnXucHFW1738rkxkgD0LSCQGUmRgFFMHwGN4PwyP3A0FUjrzuHSIewFwDh5MLx+srOR48ET8qyCH4COYKOZgZUdAroAQPigaQh2GAyOMIHNBMAMNNSIAYAuQx6/6xu9LV3fXY1VXVVdX9+34+9Zmu3fVYVT39q9Vrr722qCoIIYQUkxFZG0AIIaRxKOKEEFJgKOKEEFJgKOKEEFJgKOKEEFJgKOKEEFJgKOKEEFJgKOKEEFJgKOKEEFJgRqZ9gokTJ+qUKVPSPg0hhLQUjz766KuqOilsu9RFfMqUKRgcHEz7NIQQ0lKIyJDNdgynEEJIgQn0xEVkJIA/lxcAuBTAmQBmAlihqpekax4hhJAgwjzxDwG4WVWnq+p0AF0AjgVwOIC1InJyyvYRQggJIEzEjwTwERFZISI3ADgJwM/U1K/9DwDHee0kIrNFZFBEBtetW5esxYQQQnYQJuKPADhZVQ8H0AlgFwAvl9/bAGCy106qulhVe1W1d9Kk0M5VQgghDRIm4k+o6pry60EAm2CEHADGWOxPCCG5ZGAAmDIFGDHC/B0YyNqixggT4aUiMk1EOgB8HMBomJg4AEwDsCpF2wghJBUGBoDZs4GhIUDV/J09u5hCHibi/wpgKYCVAB4C8FUAB4vIQgBfAHBzuuYRQlqZtLzhsOPOmwds3lzdtnmzaS8agSmGqvoUTIbKDsoZKacBWKiqf0nRNkJIC+N4w46YOt4wAPT1pXvc1au99/VrzzOS9kTJvb29yhGbhJBapkwxAltLTw+walW6x03r3EkiIo+qam/YduyYJIRkQlresM1xr7wSGDWq+v1Ro0x70aCIE0Iyobs7WnuSx+3rAxYvNp63iPm7eHG8ME5WUMQJIZmQljdse9y+PhM6GR42f4so4ABFnBCSEWl5w63kZdvAjk1CSOIMDJh0vdWrTRjjyitbV0TTwrZjM/V64oSQ9iKt1EHiDcMphJBEaaWBNEWAIk4ISQRnlKRX/jVQzIE0RYDhFEJIbGpDKF7ETR0k3tATJ4TExiuE4qY2xa9VKgjmAXrihJDYBIVKenqqs1PY8Zks9MQJIbHxC5U4tUjc4syOz2ShiBNCYhNl9GUzKwi2Q9iGIk4IiU2UUZJp1UyppZUmfgiCIzYJIU3FK5Nl1Kjkh8YXodxsECxFSwiJTRrhiGbVNmmliR+CoIgTQjwpejiiWWGbrKGIE0I88csimTs33nGb9XBopYkfgqCIE0I88Qs7rF8fT3CblWLYLiVp2bFJCPEkqA4KUD+Ix5YRI4wHXouImaCBGNixSQiJRVjYodEwSDNTDFs9RxygiBNCfOjrA0ql4G0aCYM0I1Zd9E7ZKFDECSG+LFxYL7i1DA1F83ibEatup6H9jIkTQgJxplrzi4+LVMe40xi4E5VWiLszJk4ISQRnVvj+/nqvvFbAgXx4vH7x9QkTWi9OThEnhFjhFQbx+yGf9ahIr7h7VxewcWPrxckp4oQUhDxkWzhe+fCw+dvT471d1qMivR44Y8cCW7dWb5eHXw1xoYgTUgDymm2R51GRtQ+cDRu8t0v8V8PmzcB++wEHHQRs2ZLwweuhiBNSAPKabVGkUZGp56erAp/8JDB6NPDcc8Af/wh0dCR0cH8o4oQUgDxX5Kv1ePMo4EDKvxq+/W0T51q61Kxfcom5IU0Qcc6xSUgB6O72TvHLOvZcJJyHy7x55uHX3d1Y2YAqfvtb4KSTKuuHHgo88ACw006xbI0CRZyQAnDlld4TKeQh9lwk+voS+qXw5z8D731vddtf/wrsuWcCB4+GVThFRCaLyOPl1zeIyEMiMj9d0wghDkWKPXuRh8yaRPjb34wL7xbwFStMPDwDAQfsY+JXA9hFRP4OQIeqHgVgqojsk55phBA3RYk915LXzJpIDA8DZ58N7Lor8OKLpm3pUnNBhx2WqWmhIi4iJwJ4E8ArAKYDuKX81t0AjvXZZ7aIDIrI4Lp16xIylRBSRPKaWWPN1VebDspbbzXrl19uxPu887K1q0xgTFxEugD8M4AzANwGYDSAl8tvbwBwiNd+qroYwGLA1E5JylhCSPHIc2ZNIL/6FXDqqZX1Y44xHZldXdnZ5EFYx+YXAHxPVV8XEQDYBGCX8ntjwBRFQkgIhcusee45M1jHobMTePllYNKk7GwKIEyETwZwiYgsB3AQgNNRCaFMA7AqNcsIIS1BkvnZqXaQvvEGsPvu1QL++ONm1GVOBRwI8cRV9XjndVnIPwrgfhHZC8CpAI5M1TpCSOFJKj/b6SB14utOB6n7HA2xfTtwxhnAL35RafvJT0xHZgGIXE9cRMYDmAHgPlV9JWx71hMnhCSB35yfPT0mW6chFiwAvvzlyvqXvpSb5PvU6omr6muqeouNgBNCsqNlcrPLJNpBescdJuHeEfCTTjIlDnMi4FHgiE1CWpDUQg8ZMTBgHkbbt9e/F6mD9OmngQMOqKyPHWvc+AkT4pqYGcwuIaQFKXxutgvngeQl4NYdpBs2mIE6bgF/8kkzS0SBBRygiBNSOGzCJH7zYfq15xmvBxJgxt+Elh7Ytg2YMQMolcyQeQC47TYzWMct6AWGIk5IQRgYACZONAMFw4aw+1VAbUJl1MTxi3kPD4cI+Pz5Jsf7N78x61/5irlpH/tY4jZmCUWckALghBTWr69/zytM4hV6CGrPM5Enc/jpT02npRNnOe0045G7s1BaCIo4IQXAL6TgUOut+s19CRQvU8V6sNAf/2jE+6yzzPqkScBrrwG//GUxf4JYQhEnbUVR0+7C0uhqvdKZM/23HRoyIZmJE4tx/aFleNetM/VMDjqostMzzwBr1wK77ZaJzU1FVVNdDj30UCUkD/T3q44apWoCo2YZNcq0552enmq7g67B6zqD9p0zxxxfxPwtwv1QVdUtW1SPPbb6gpYty9qqxAAwqBYaSxEnbYOfEPb0ZG1ZOH7CXCrVi26Q4HstIgV8sP3TP1Ub/Y1vZG1R4tiKOMMppG0obElUVEIKpVKlrVQCFi6sz9CIej21lTdynU8+MGBiKt/6llk/6yzTW/u5z2VrV4ZQxEnbEDnLocnYxOvfeqvyev167/TCJK4n7oMt8b6HwUEj3s5EDHvvbQbq3HKLOUk7Y+Oux1kYTiF5Ic8xcRvbgsIk7lh2lJh40PHSvBZr1qypN+755xs3rkCAMXFC6unvz2cnnk283qaT0i3kUWPjST3YEul7ePtt1d7e6gP8+teNG1VAbEU8cinaqLAULSHhjBhRH5sGTARheNi8HjkyfLBObVnWiRO9Bwh5nUfV7N9IrW83Ntfiiypw6aXAd79babv2WmDu3MYNKii2pWhZxZCQHGAzhZnNaMvaWLaNgAMVAW+4LreLhqdjW7IEuOCCyvp55wE//KFRf+JLm/cIEJIPbEYlBo3CdIjTqZlUlk7k6dgeesgItSPg++wDbNoELF1KAbeAIk5IDggdlQhvcXTjJZTulMQwksrSsbkWAMBLL5kNjj660rZqlZmoePToZIxpB2wC53EWdmwSkhzuDssRIyp9fl6Dfpzt3dtFGfWZWgfw5s2qH/xgtQH33pvgCVoDcLAPIa1HX1/FI3d3Errzx2u3Hz8+/Li77FJ5PTBgIhvucrcXXJBArrcqcNFFxvinnzZtixaZ9uOPD96X+EIRJyRH2AySmTvXf9YeZ38Rk80iYte56R44NHcusGVL9ftbtsRMELn+enNRN9xg1i+6yDyFPvOZGAclALNTCMkNNvNiDgz4i7KzvbN/1NrhzoPA7/i2mS5V3HsvMH16Zf3AA4E//KHa9SexoCdOSMJEGXLu3vb888PnxQyqadLREVxz3IbE6sgMDZmfAW4Bf/FF4IknKOAJQxEnJEEcbzps+jSvbf08Z7ewBolsErP2dHf7Z7RYZbq8+SbwvveZJ5PDgw+aC3z3u+MbSOqgiBOSIFFmmQ+brcfBPRm7XxrgmDHxU6qdFMWFC83UlG46O027L6om5jNmDPDCC6ZtyRLTftRR8QwjgVDECUmQKOVubUMXGzdWPHm/gTQ77eQ91N29TZAn7c7l7usz/Y7OjGYdHWbddyj+tdeaeNCPfmTWL73UdFp+6lM2l0diQhEnJEHcXrMbLw/adnDN1q0VT95vIM2GDcHH2GUX4OyzvR8A/f2V4fZOZsv111fCM9u3Azfd5BES+s1vzMaXXWbWDzsMePtt4LrrONKymdgkk8dZONiHtAv9/apdXfUDaTo7/QfiRKkuGDTgxqZiYdBUbDbla3dUIXz++fo316xJ9F4S+8E+rGJISEJMmeJd+KlUAl591Xsf2yqDgPGaPYevoz490Q+vIlcDAyYzJqxjdCz+ho3v+gDw8suVxkceAXpDC+2RBrCtYshwCiEJ4RfjXr/eP83QqxPRj9oOUnd64rx5RoidMIutjY74Bwm4YBi34kxsxK4VAe/vNz44BTxzKOKEJERQjNsrzXBgwIjv1q3253BE2CuV8aabTMfn8LB/xcNaG8MyZD6Hb2AYHTgTPzMNn/1sJROF5AKGUwhJiLCQhjuUYRv+8DtGUOhmzJjKWBv319srHOM3gcOpWIZlOG3H+tr9jsPuT95j/7OBxCbRcIqITBCRGSIyMb5phLQmTuaIH0NDFW/cq/5JGO5Ss0GhG0fcVSuhFb9ysLWe+X54BgqpCPhOOwFr12L3Z+6jgOeUUBEXkfEAfgngcAC/E5FJInKDiDwkIvNTt5CQguHkV3sxezZw8cXR65CMGVMR4YEB+wne1TVjj1cExMk7H4fXsQ4T8Qw+UHlz5UqTMjhpUjRjSVOx+Vf4EIDLVfVKAP8B4EQAHap6FICpIrJPmgYSkjRRaptEPW5YJ+HmzcHeuh9vvgk88IDJZjnvvGhD7IMGFfWdux3P7fsRvI7xmAjzZLnvH2816j9tWnRDSfOxyUMsx82PB3AfgBsBzCy3nQvg7z22nQ1gEMBgd3d3M1IqCbHCKx867uzuDo3OLm+7iPi/19FhJoaINMv8FVdUbzh/fvybQBIDSU4KISIC4BwArwFQAE6i6AYAkz0eDItVtVdVeyfxpxjJEVFqm9jg9uq9Ohq98Au3lErB82gG5SA4nnlt2NpzbsvbbjPB8iuuMOszZpgUmQULgswmOcVKxMsPhksAPAHgaABOLckxtscgJA9EqW0SRm2anw1dXdXVWd2cfbYR3EZHrK9fb/YtlXzmtnzqKfPGGWeY9XHjzE53321mkCCFxKZj8/Mi8sny6m4Avg7g2PL6NACr0jGNkOTxy+WOMkmw432fd170DJMtW4B77vF+b9kyI7hxJrvZssXocne3eSD09cE0jBljJmRwePpp4PXX/Yu9kMJg40UvBjBLRO4D0AHgtvL6NQDOBnBnivYRkih+VQDrQg4+uL3vpHF+DRxzjPHY3YwcGS3Db2gImPPpbXjlgyea3tA33zRv3HGH+dmw//7JGE0yJ1TEVfU1VZ2hqser6sWq+gaA6QAeBnBCeZ2QQuBXBTBsAGIc79sW59eA1xyX27YBu+5abXdQadkr8SVsfKsTe/zn70zDggVGvE8/PR3jSXbY9H7GWVjFkNTS3+9dSS+v2FT4c5auLv8skbBlzpzgyoYi4XadhZ9UNdyGj6pu25bNjSOxgGV2CnszSFOxmQw4b9jOwNPT44pDI3oH5bJlZvGjNm7vnGfePGD80ON4HIfseO8VTMZ+eBbje8bhYwGDj0jxyW1mSVoDMki2JJ3i1wzCMlfcEyvEeRCtXh18rpkz69v6ZqzFqpdGVgn4vngWe+IVbBs1zjrWT4pLLkU8ymSzpFgkmeIXhyhOQlDmSm1M3X3cqEyYEJwsUjW7zpYtwNFHA5Mn70gS/+3/vgtTehTPy77WsX7SAtjEXOIsjcTE/Ua++Y48I4UhD5+tVyy5s9PEsr3i9LajPG1j5yNGeLeXSuHx9J4eVb3ssurGq65q3s0jTQOWMfFcirjf8OLajh1SPNIc9m6L7VRmtUIe1hlrc1yv6dtsl/Pww6qGvxx5jur27c25aaTp2Ip4LsMpSQzIIPmkr8/MQOOeSf3885v7s98mdFMbp+/rMzHv4eH62LcTQrHJHVcNTg304jCsgEKwFGbM3Sr0YCw2Yt9Hf4yBm3P5FSZNJJf/AXEHZJD8MjBgYruhM6mniK0zYCP2UQf/OLP42Azc2QNroBCswBE72qbiBbwHq7AJY7F1a747hElzyKWINzogg+SfPGSneDkJXtiIvW36oRunxokfO+FtPIpDsAZ77Wg7EfdAoPgLplZt2+wOYZI/ciniQPDPV1Jc8pCdUusklEr1w9xtf/kF2e1XrbCjo35EpkHxXVyMt7ELDsHjpum66zClR/E7nOh5LIYYSW5FnLQmeenvcDsJr74K3HhjY7/8/Ozu6TFhIq+woNeEDhfiB1CMwMVYBAC4eafzjXGXXoorr6x/yAAmJMMQI6GIk6aSl/6O2jzxBx5o7DhB1+PXieuuGX40HoBC8AN8GgDwDPbDbp1vYviGf98Rc+nrMw8Zd4doqQQsWcJfqAT5TDEkrU0WtVPc5yyV/HO1w/LA3XncpZJpC2r3SqecM0d1n51X1510bwzt2LfRaytCLRpiB4qcJ05IVIKELEoBK79BOCed5P/+/vvXH99vrMPO2KzPdX6gqvFY3Ff38LAV5jzk3ZN0sBVxMdumR29vrw4ODqZ6DtK+DAyY0q21s8ePGlWZkPj886NNLJwOihtwIS7Akh0tX5zwfXx9w+y6LUsl4K23qrNenOupDZ/45ac7M9yT4iIij6pqb+h2FHFSVGorItYyerTJy/bOBGkeF+O7+C7+Ycf6YszG6KXXY9YnBVG+fl7CPGIEPI8hYvpFSXGxFXGWoiWFJSxH25nMJis+jOVYjhN2rK/ENByJh/EOdgZmmY7OKL8QnHTGgQFz7atXGxH3OgZTD9sHZqeQRGhm6eAow9yzYAr+AoVUCfheeBkHY6UR8DJe4jtqlP+w/O7u+gqffsdg6mH7QBEnsWlm6eA057iMy2hswguYWjWq8gg8DIFWjb70Q8TE7xcu9E9bDPv1wdHNbYhN72echdkprU8zy8vaVAps9iLYrjfjnKrGWbipoWM598wvO8Uv6yWt+02yA0WuYpgknCEofWyH0vt9FlE+o7x54JfhGgyjA+fiJwCAazEXguEdFQej4twzv7ITQbFu1lFpU2yUPs6SpSfOHNrmYOOJz5lT70U6A19sP6OgSYSbvZyMu6saHsIR2oW3Yx83zJvu7/f3xumJtxbgYJ98zCLTDoQ9LIOEp6PD/zNyQgpA+AjLZi3vxX9VNWyH6O54JZFj2zoYfg9EOietBUVcOUNQMwkaYdhoHDvOKMukl7F4Q1/GnlWNB+PRxI7f0RFNhDnUvvWhiCs9cdV8fNmDOuP8PHG/9mYvI7CtrvEc3JzKubw+pzx8fiQaSX1mFHFlTDwv1+/3MBXxjonnZfklZlY1fB2fS+1ccfsLSD5I8jtHES/Tzp5MXn6JeP1jOwLuvB82y3szl/+Fa+oak+i0tBVwZwnqLyD5JMnvnK2Is3ZKC5OnuhruoeLd3ZV62w55GIF5LO7H/Ti+qm1vrMZL2Nv6GKrBU6/19AAzZwLLllXuRdTrZl2U/JLkd862dkrL54m3M3mZRQcIn24vyxxnZ0Jit4CfjF9DoJEE3Bku7570wev96683f5cuNffCb3u/6d1YFyW/ZPGdo4i3MGnPohN3IJV7/xEZ/CeOxFYopGpI/JdwJQSKe3BypGN1dZnh8oD3fe/qAjZu9C5N4Pc5zZ6dj1mQiD2ZzFxlE3OJs2QdE2930uoTiNuBE3eihrjLchxf1bAcxzd8LK/0wNr77hfzDxtm3859OkWl2dkpjImThvCLYZdKwJgx/rHvsP07OkzIZcIEs75+ffSSrUF8EV/D1zCvqq0TW7ANnaH7OrFu91fGPflEUMw/T/0TpBgwJk5Sxa8zbv16u2qGfjFwR6zHjAEOOsiIXBICfhJ+A4VUCfie+CsEaiXggLmmpUtNDFukUjEQCK/imKf+CdJihLnqAMYBuAvA3QB+DqALwA0AHgIwP2x/hlNaj6Bh9LbpVc2qRrg3huoa3XNaRllqr8NdFiBs+7zk7JPigASrGPYBuEZV/xuAVwCcC6BDVY8CMFVE9kn+0ULyzLx53qEBP7y8bq8OoCTpwjtQCFajZ0fbZbgGAsXvcVxDx5w5s/Lapq65+7r7+ozXXuvFs+43iUukmLiI/BTArgCuVdVlInIugF1UdUnNdrMBzAaA7u7uQ4eyTgAmieIX3/Wjdm5IJ2d8aCjZeLfDI+hFLx7dsb4Mp+I0LIt93M5OYMkSI7wTJ9ZPzlwLJysmcUh8jk0ROQrAeACrALxcbt4A4JDabVV1MYDFgOnYtD0HKQZRBqjUplfVTm6cpIAvwHzMR3UuVwe2YRg+CdcR2brVPHyAcAFnKiBpFlYdmyIyAcC3AVwAYBOAXcpvjbE9BmkdbEMhXiGDsOnFGmEm7oRCqgR8EtZCoIkJuMPq1RUh94OhEtJMQj1xEekCcCuAL6rqkIg8CuBYAA8DmAbg2XRNJHnDEae5c4M9Uq9QQpIjM9+DP+PPeG9V2xF4GCtwRHInqWHEiOBfIf39FG/SXGy86AthQibzRGQ5AAEwS0SuAXA2gDvTM4/klb4+4NVXgdGjvd/3m7Hdyf+Ow854CwqpEvA5+B4EmqqAA+Hhn3nzOAUgaS6hIq6qi1R1vKpOLy83AZgO44mfoKpvpG0kyS/f/74ZUu7GPQQ9WRTPYl+8hUos5xacBYHiesxp6IhJD/cPyo0nJA0a+hdW1ddU9RZVfSVpg9qdPEzsHMWGvj7gxhurU+duvNE/pLBhQ2M2fQuXQzEC++K/AADvoAsjsB3n4JbGDlgmjQHLmzeHx83zTB7+B0kEbJLJ4ywc7GNPHgaEpGlDf3/0uTLPwM/qGnfDhqYMFIqzFHUKwDz8DxIDWDulePjVE2lmvnFaNgwMABdcAGzZYrf9vngWz+L9VW0H4zGsxMGNG9FEipojnof/QWJg7ZQC4pe50cxa22nZMG+enYCPxiYopErAP4UlEGhTBTxoYocwvHLEixKiyMP/IIkGRTxH5KFIUlo2hIuA4iW8C5swdkfLv+N8CBQ/lE/FO3lESiVT6KqRsgBeOeLuIfqq+e78zMP/IImITcwlzsKYuD15iEemZUNQoahF+J9VDa9iggLDmcSy3dcaVuCqdvGqKx507XmcKzMP/4PEAE6UXEyynATALVrOJL1J2dDfXy9i/x0DdY1j8UbThbtUCr7fXrYHdWjW3regio95nOiBE1HkA4o4UVX7L2QzPLA5c8xxD8ATdWq2P57KxPP28oa97pnfzDw2Xn2YN09Pl3hBESeRhLkpP/nffFPf2GPfqhOcg5sTE+QoNc797oXfPXMeQI08JGymostjaIVkC0WcRBJmPwFsJN+5zpNdOqw6a1bVgb+Di2MJdqkU3TsulcLDRUH3rBFv3Ll/YR55UfPKSXpQxEmgZ1rrgSblidd6nf+A66oOeO8H52jcTkvHM44y0bLjdYf9Ogl6mEWJjfvdvyJ1cpJsoYiTQM+vNpSQVEzc8Van47dVB3ui6xD90Y1vRQ55eIldlKyR2r6AsFnnw0Q2ijful+lSew8YEydeUMRJaCzWb87IRrMS+vtV34MX6k60B/6645hxBNwdcrB5GHhdX9ix+/tVOzu9t3FCMLbndgt40OdQKmUn4sxEyS8U8TbG/cUM8hwTjcP+7W/6Ykd31Ql6saJK1OJ64aVS5XQ2GR9z5lQLVNC9cHK8+/tVu7rsHii299Xm4ZWFN86c8HxDEW9TvL6YfoLjFsWG2b5dVx1+VtWBz8MP684VdeBMmIcbdJ09PdFj5o6ARQmXOJ65l41ubB9ezY6LMz6fb2xFnMPuWwyv6c9UvbfduDHm0O+rrwY6OtCz4lYAwDW4DAJFP2ZVbVYqmWHoQdO62db1doasA/Wzxy9dambWAYBFi6JPA7d5c/jcmW62b/eusbJpU/V9tR2yvnp1c2ussE5Ki2Cj9HEWeuLNJWrIoiGv6667qg5yP47RTrxjFSZodOCMjd02+djNWmo7NW1CNKVSc8Mb9MTzDeiJJ0NRqs85RJ3+LJLX9dxzxvU89VSz3tGByfh/OA6/x1Z01W1eKlUXgxoYCJ+Xs6M8r3FYFUEvu+fOjT8J84gRjRW+qqV2Ygi/X0MOzjlr7U9zggmvX0ZeFRhJzrFR+jhLkT3xonX8+Hl8nZ3hqXWBvP666uTJ1Ts+9piq2qcx2nrJtoNjHLuTirW7l6SO6eSW+8XO3RNkNK0DugZmp+QXsGMzPkX7uelnr5PCFvmBtG2b6umnV+10Nn5S9WUPG44eln/tt0+Q+Dsho1LJLkwRZenoqFx+3PCMV3ikkSWv/28kXSjiCZDkUPRmEGZvJK/rq1+tOsg3R37R8wEQJs7OuePUNQkaKJPG4iZO8askYv95/uVH0oUingCt4olHsvf226t3Pukkndq91fe4YaLaiCfuLLUpkEmHTWzvVdTzOg/IuA8cv/rkpD2giCdAEWPiDdv79NPVO44Zo/rqq6oa7OEnHROvXdy2RxXFrq5o3rBXLfCo53X/SvO7Nx0ddnbl9RcfaQ4U8YQoWsdPZHvXr1cdO7ZaPZ58smqTIA/fT5ydOHzt6NGoIQa3ZxzVI3Zs8BtGH7S4H0BR4/nuz8LvocrytCQMinhCFE3Erdm6VXXGjGrV+PnPPTf161ycM6fyvtc98hOxKGLq9kYbqSLoPDxGjw7eJkhEbUMjfvXJ/f5/WBSLBEERT4CihVNULR868+dXX9QVV4Qed86c6EKT1DB7N412Fnp1lEapLRN2/LhFrFrWWSANQxFPgKJ1bIY+dG69tfrN004zaYQWBKUv+olPlFhyV1d92MN25p3OTrtqnco+AAALsElEQVRUQ6+qhrZVHv1yvYvycCfFgyKeAEVLMfQT2lP2XFndMHGi6muvRTq2rSA3Ekt2F7WynQ+0djt3m41nHWZfrSjbXgchSUERT4CieeK1AjYRa/Ud1Li3f/pTQ8dupHPPpmZIGg9E288tyC7bmY+8zsGQCEkCWxFn7ZQAilZbwqmWNxJbcS+Oxzrsji5sNY133ml05v3vb+jYQRUIa3HqmvT1AWPH2tlsg20dG5vPLagGjlN1MeyYtYiYKouqlWqLea+1Q1oAG6WPsxTZE1fNpsOp0XP296v+28jPVrmG8zq/kZjNtXbZ1GMJCm/YxpH9Rk0G7R92D4M8a78660HZJGEZLoREBQynFJOGM2IGBqp2uhWf0IkTtif60KkVRq+JF2ptDRrwYivgUaaYsyUsxh/1XjQrXMQslvaBIl5QIsfhBwerNnwR79KxeCOSp2uD38Oldgo0m2ySKHbZ1maJSpjwRr1vzeg/KWLKK2mcREUcwGQA95dfdwL4BYAHAFwQti9FPBrWGTFr1tRtNBXPh4pIo55cHJGK4z3a1maJSlina9TjNkNgi9bRTuKRmIgDGA/gVwAeK69fDuCK8utlAMYG7U8Rj0boF/Xtt1UPO6z6zV//2kr84whNVumWYZ543AE2th5+WFqjE15KM9RRtJRXEo8kRXxXAOMALC+v3wFg//LrLwA4wWOf2QAGAQx2d3c38bKLj6/QLh1WveSS6jeuvXbHfjZeWhxPLisvMGjIexITPdtcl+0Ao7RDG/TE24vEY+IuEb8HwDitiPW5QfvRE49OrYf34Owl1d/avj7V4eG6fcK87DieXJbx2EaG/Ntic12NFsBKGsbE24s0Rfx2AHuUX18O4H8E7deOIp5YBsGDD1Z/Y/fZR3XTpobPG9eTyzIzwqaQlK1dUcMgjZaiTQNmp7QPaYr4lwGcWX59E4Cjg/ZrNxFPxFt66aV6dVi1Kh+2NXjeOCIbtH3Ua2rkHuTFEyftRZoi3gPgaQALATwCoCNov3YT8Vje7ubNqgceWL3j8uWJ2peUJxelzkkaIuseeBPlfjfy+TQzJk5PmzikmicOYC8AZzux8aCl3US8objz8LDqhRdW77BoUeq2xhkZaivMUUWz0Y5G2/vdaL+ATXZKEgLOmDdx4GCfjIjs6S1aVL3hhRfWdVqmQRzBiHKNUUXTZnub8EaSnnizyLNtpPnYijgLYCWMddGs++4zFZPmzDHrBx4IbN4M/OAHpj1l5s0zp3OzebNpD8MpcGXT7lfgKk673/nd+BUpy2NRM6ew19CQ9/s210vaGBulj7O0myeuGvIze9WqelfrxRebblPUMISbKB5jGjHxME88LH88T3Fnm9AQPfH2BAyn5IxNm1Tf976qb+cZezzYFCHxEoqoVffcwlcq1XfqdXaa9jRSAG3qsaQVQ047Fh72QGJMvH2hiOeF4WEzOMf1zXzw0zc2tQPLTyhsB9D4ZWc4ou0l6mmLjzs7xZk6LemHYTOyUoJy0LP+lUCyhSKeBxYurP5WXnKJ6vBw0zuwwoQizKMMs7dVO+SakR/eqveOxMdWxNmxmQb33GM6J+fONeuHHQa8/Tbwne8AIpE6BpPAr7OwpwdYtQoYHjZ/a2ezCbPLaW/W9djO7JMUUexv9Frz2NFKigVFPEleeMGI98knV9rWrAFWrAB22mlHU9TMjLjEFYowe5txPQMDZrqzZk5/FsX+Rq+1rw9YvNg8UEXM38WL/R+ohNRh467HWdoinLJxo+q73139e/iRR3w3z2JQR5zOuDB7W7WWdl6qF5L2BIyJN4Ht21U/8Ynqb7TltzlPaW422GSMZF1LOw0bmjFSkxAvbEVczLbp0dvbq4ODg6meIxO++U3g85+vrH/2s8BVV2VnT4vjNxjGies74Rb3AKZRoxiaIMVFRB5V1d6w7RgTj8pdd5ngpSPgxx0HbNlCAU+ZsLh+nBGohBQZirgtzz5rxHvmTLPe2QmsXWuGz3d2Zmtbjmgkg8Rmn7AOwGZn/BCSF0ZmbUDueeMNYJ99gHXrKm0rVwLTpmVnU06pDWk4GSSAf0gjyj59ff7H6e72DreklfFDSF6gJ+7H9u3ARz4C7LZbRcBvvdX0p1HAPWkkpJFUGIT51qRdoYh7sWABMHIkcOedZn3ePCPeZ56ZrV05p5GQRlJhEOZbk3aF4RQ3t98OfPzjlfUZM4Bly4ygk1AaCWkkGQYJCrcQ0qrQEweAp5827psj4OPGAevXA3ffTQGPQCMhDYZBCIlHe4v4+vXAmDHAAQdU2p56Cnj9dWDChOzsKiiNhDQYBiEkHu052GfbNuCUU0yhKofbbwc++tHsbCKEEBcc7OPHvHkmr9sR8AULTKclBZwQUkDaJ+B7yy3AOedU1k8/Hfj5z4GOjuxsIoSQmLS+iK9cCRx8cGV98mQz+nLcuOxsIoSQhGhdEV+7FthrLzNox+HZZ4F9983OJkIISZjWi4lv2QIcc4zxuB0Bv+suE/emgBNCWozWEvHLLzcz6Dz4oFm/6ioj3qeckq1dhBCSEq0RTunvB2bNqqyfdRbw4x+bsniEENLCFFvEH3kEOPzwynp3txmsM3ZsdjYRQkgTKaaIr1ljOi3dvPACMHVqNvYQQkhGFCve8M47wKGHVgv4PfeYuDcFnBDShhRDxFWBiy8Gdt4ZeOwx03bddab9xBOztY0QQjIk/+GUG24ALrqosj5rFnDTTaZaEiGEtDn5FvH58ys1Sffbz3jhtXVLCSGkjWk4nCIiN4jIQyIyP0mDqvjwh81UaENDwDPPUMAJIaSGhkRcRP4OQIeqHgVgqojsk6xZZWbMMLVPONstIYR40qgnPh3ALeXXdwM41v2miMwWkUERGVznniWeEEJIojQq4qMBvFx+vQHAZPebqrpYVXtVtXfSpElx7COEEBJAoyK+CcAu5ddjYhyHEEJIDBoV30dRCaFMA7AqEWsIIYREotEUw9sA3C8iewE4FcCRyZlECCHEloY8cVXdCNO5+TCAE1T1jSSNIoQQYkfDg31U9TVUMlQIIYRkADskCSGkwIiqpnsCkXUAhlI9STJMBPBq1kY0AV5na8HrbC3c19mjqqE52qmLeFEQkUFV7c3ajrThdbYWvM7WopHrZDiFEEIKDEWcEEIKDEW8wuKsDWgSvM7WgtfZWkS+TsbECSGkwNATJ4SQAkMRByAik0Xk8aztSAsRGSkiq0VkeXk5MGub0kZEvicip2dtR1qIyBzX57lSRL6ftU1pICLjRWRZubR1S14jAIjIe0TkThG5X0S+FWVfirjhalSqMrYiHwJws6pOLy9PZm1QmojIcQD2UNVfZG1LWqjqIufzBHA/gP+TsUlpMQvAQDntbqyItGqa4TcALFDV4wC8W0Sm2+7Y9iIuIicCeBPAK1nbkiJHAviIiKwoT6uX77lVYyAinTCCtkpEPpa1PWkjIu8CMFlVB7O2JSXWAzhARHYDsDeAFzO2Jy32BfBY+fVaAONsd2xrEReRLgD/DOALWduSMo8AOFlVDwfQCWBmxvakyScB/CeAbwI4XEQuzdietLkEwKKsjUiR3wPoAfCPAP4EMwlNK/JTAP9SDgGeAuAe2x3bWsRhxPt7qvp61oakzBOquqb8ehBAOnOi5oODASxW1VcA9AM4IWN7UkNERsBc3/KMTUmTfwHwGVX9VwDPAPj7jO1JBVX9KoC7AFwE4CZV3WS7b7uL+MkALhGR5QAOEpEfZGxPWiwVkWki0gHg4wD+mLVBKfI8gKnl170oRt2eRjkOwB+0tfOExwM4sPy/ewSAVr7WlQC6AVwTZSfmiZcRkeXlTqKWQ0QOAPAjAALgDlWdl7FJqSEiYwHcCDPvayeAM1X15eC9iomIfA3AoKr+36xtSQsRORzAEpiQykMAzojipRYJEfkKgOdVdWmk/SjihBBSXNo9nEIIIYWGIk4IIQWGIk4IIQWGIk4IIQWGIk4IIQWGIk4IIQWGIk4IIQXm/wMhUNfdSY2KbQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y, color='b')\n",
    "plt.plot(x_train, linearRegression2.predict(x_train), color='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_predict = linearRegression2.predict(x_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### MSE(均方误差)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "MSE：Mean Squared Error，均方误差：\n",
    "$\\frac{1}{m}\\sum\\limits_{i=1}^{m}(y_{test}^{(i)}-\\hat{y}_{test}^{(i)})^2$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24.15660213438744"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mse_test = np.sum((y_predict - y_test) ** 2 / len(y_test))\n",
    "mse_test"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### RMSE(均方根误差)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "RMSE：Root Mean Squared Error，均方根误差：\n",
    "$\\sqrt{\\frac{1}{m}\\sum\\limits_{i=1}^{m}(y_{test}^{(i)}-\\hat{y}_{test}^{(i)})^2}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.914936635846636"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rmse_test = np.sqrt(mse_test)\n",
    "rmse_test"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### MAE(平均绝对误差)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "MAE：Mean Absolute Error,平均绝对误差：\n",
    "$\\frac{1}{m}\\sum\\limits_{i=1}^{m}|y_{test}^{(i)}-\\hat{y}_{test}^{(i)}|$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.5430974409463873"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mae_test = np.sum(np.absolute(y_predict - y_test)) / len(y_test)\n",
    "mae_test"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 调用自己封装的函数计算MSE、RMSE、MAE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "from common.metrics import mean_squared_error\n",
    "from common.metrics import root_mean_squared_error\n",
    "from common.metrics import mean_absolute_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24.15660213438744"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_squared_error(y_test, y_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.914936635846636"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "root_mean_squared_error(y_test, y_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.5430974409463873"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_absolute_error(y_test, y_predict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 调用scikit-learn中的MSE和MAE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import mean_squared_error\n",
    "from sklearn.metrics import mean_absolute_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24.156602134387438"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_squared_error(y_test, y_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.5430974409463873"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_absolute_error(y_test, y_predict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用$R^2$来衡量回归算法的好坏"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$R^2$：R Squared,\n",
    "$R^2=1-\\frac{SS_{residual}}{SS_{total}}$，其中$S_{residual}$表示Residual Sum of Squares，$S_{total}$表示Total Sum of Squares\n",
    "$R^2=1-\\frac{\\sum\\limits_i(\\hat{y}^{(i)}-y^{(i)})^2}{\\sum\\limits_i(\\overline{y}-y^{(i)})^2} \\quad\\quad \\Longrightarrow \\quad\\quad R^2=1-\\frac{(\\sum\\limits_i(\\hat{y}^{(i)}-y^{(i)})^2)/m}{(\\sum\\limits_i(y^{(i)}-\\overline{y})^2)/m} \\quad\\quad \\Longrightarrow \\quad\\quad R^2=1-\\frac{MSE(\\hat{y}, y)}{Var(y)}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6129316803937322"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1 - mean_squared_error(y_test, y_predict) / np.var(y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将以上代码封装到一个py脚本中进行调用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "from common.metrics import r2_score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6129316803937321"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r2_score(y_test, y_predict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "调用scikit-learn库中的方法计算$r^2$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import r2_score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6129316803937324"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r2_score(y_test, y_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6129316803937321"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression2.score(x_test, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 实现多元线性回归算法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备测试数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = boston.data\n",
    "y = boston.target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(506, 13)"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(506,)"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = X[y < 50]\n",
    "y = y[y < 50]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(490, 13)"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(490,)"
      ]
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [],
   "source": [
    "from common.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = train_test_split(X, y, seed=666)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(392, 13)"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(392,)"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 调用外部自己封装的py脚本解决多元线性回归问题"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [],
   "source": [
    "from linearRegression.LinearRegression import LinearRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [],
   "source": [
    "linearRegression = LinearRegression()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression()"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression.fit_normal(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "34.117399723204585"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression.intercept_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1.20354261e-01,  3.64423279e-02, -3.61493155e-02,  5.12978140e-02,\n",
       "       -1.15775825e+01,  3.42740062e+00, -2.32311760e-02, -1.19487594e+00,\n",
       "        2.60101728e-01, -1.40219119e-02, -8.35430488e-01,  7.80472852e-03,\n",
       "       -3.80923751e-01])"
      ]
     },
     "execution_count": 105,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8129794056212895"
      ]
     },
     "execution_count": 106,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearRegression.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 调用scikit-learn中的方法解决多元线性回归问题"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [],
   "source": [
    "# sklearn的训练集和测试集的分割算法和我们自己实现的有所不同，\n",
    "# 所以会导致最后模型算出来的参数不同\n",
    "# from sklearn.model_selection import train_test_split\n",
    "# X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(392, 13)"
      ]
     },
     "execution_count": 108,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(392,)"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(98, 13)"
      ]
     },
     "execution_count": 110,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(98,)"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "\n",
    "skLinearRegression = LinearRegression()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,\n",
       "         normalize=False)"
      ]
     },
     "execution_count": 113,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "skLinearRegression.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "34.117399723229845"
      ]
     },
     "execution_count": 114,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "skLinearRegression.intercept_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1.20354261e-01,  3.64423279e-02, -3.61493155e-02,  5.12978140e-02,\n",
       "       -1.15775825e+01,  3.42740062e+00, -2.32311760e-02, -1.19487594e+00,\n",
       "        2.60101728e-01, -1.40219119e-02, -8.35430488e-01,  7.80472852e-03,\n",
       "       -3.80923751e-01])"
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "skLinearRegression.coef_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 调用scikit-learn中的KNN Regression解决回归问题"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5865412198300899"
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsRegressor\n",
    "knn_reg = KNeighborsRegressor()\n",
    "knn_reg.fit(X_train, y_train)\n",
    "knn_reg.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用网格搜索的方式，查询最好的KNN回归模型的超参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\CandyWall\\Anaconda3\\lib\\site-packages\\sklearn\\model_selection\\_split.py:2053: FutureWarning: You should specify a value for 'cv' instead of relying on the default value. The default value will change from 3 to 5 in version 0.22.\n",
      "  warnings.warn(CV_WARNING, FutureWarning)\n",
      "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 3 folds for each of 60 candidates, totalling 180 fits\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=-1)]: Done  34 tasks      | elapsed:    7.4s\n",
      "[Parallel(n_jobs=-1)]: Done 180 out of 180 | elapsed:    7.8s finished\n",
      "C:\\Users\\CandyWall\\Anaconda3\\lib\\site-packages\\sklearn\\model_selection\\_search.py:841: DeprecationWarning: The default of the `iid` parameter will change from True to False in version 0.22 and will be removed in 0.24. This will change numeric results when test-set sizes are unequal.\n",
      "  DeprecationWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv='warn', error_score='raise-deprecating',\n",
       "       estimator=KNeighborsRegressor(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "          metric_params=None, n_jobs=None, n_neighbors=5, p=2,\n",
       "          weights='uniform'),\n",
       "       fit_params=None, iid='warn', n_jobs=-1,\n",
       "       param_grid=[{'weights': ['uniform'], 'n_neighbors': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}, {'weights': ['distance'], 'n_neighbors': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'p': [1, 2, 3, 4, 5]}],\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',\n",
       "       scoring=None, verbose=1)"
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "param_grid = [\n",
    "    {\n",
    "        \"weights\": [\"uniform\"],\n",
    "        \"n_neighbors\": [i for i in range(1, 11)]\n",
    "    },\n",
    "    {\n",
    "        \"weights\": [\"distance\"],\n",
    "        \"n_neighbors\": [i for i in range(1, 11)],\n",
    "        \"p\": [i for i in range(1, 6)]\n",
    "    }\n",
    "]\n",
    "\n",
    "knn_reg = KNeighborsRegressor()\n",
    "grid_search = GridSearchCV(knn_reg, param_grid, n_jobs=-1, verbose=1)\n",
    "grid_search.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'n_neighbors': 5, 'p': 1, 'weights': 'distance'}"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最好的超参数组合是\n",
    "grid_search.best_params_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6340477954176972"
      ]
     },
     "execution_count": 123,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 回归准确率\n",
    "# 这个计算的准确率是通过CV（Cross Validation）后算得的，跟我们上面的验证方式不同\n",
    "grid_search.best_score_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7044357727037996"
      ]
     },
     "execution_count": 124,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 获取网格搜索后的KNN Regressor算法，调用score算出来的准确率，\n",
    "# 才能跟上面我们实现的多元线性回归算法进行比较\n",
    "grid_search.best_estimator_.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线性回归参数的可解释性和更多思考"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(490, 13)"
      ]
     },
     "execution_count": 125,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(490,)"
      ]
     },
     "execution_count": 126,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,\n",
       "         normalize=False)"
      ]
     },
     "execution_count": 127,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "lin_reg = LinearRegression()\n",
    "\n",
    "lin_reg.fit(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1.06715912e-01,  3.53133180e-02, -4.38830943e-02,  4.52209315e-01,\n",
       "       -1.23981083e+01,  3.75945346e+00, -2.36790549e-02, -1.21096549e+00,\n",
       "        2.51301879e-01, -1.37774382e-02, -8.38180086e-01,  7.85316354e-03,\n",
       "       -3.50107918e-01])"
      ]
     },
     "execution_count": 128,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lin_reg.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 4,  7, 10, 12,  0,  2,  6,  9, 11,  1,  8,  3,  5], dtype=int64)"
      ]
     },
     "execution_count": 132,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.argsort(lin_reg.coef_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['NOX', 'DIS', 'PTRATIO', 'LSTAT', 'CRIM', 'INDUS', 'AGE', 'TAX',\n",
       "       'B', 'ZN', 'RAD', 'CHAS', 'RM'], dtype='<U7')"
      ]
     },
     "execution_count": 133,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 获的排序后的系数所对应的特征的名称\n",
    "boston.feature_names[np.argsort(lin_reg.coef_)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1.23981083e+01, -1.21096549e+00, -8.38180086e-01, -3.50107918e-01,\n",
       "       -1.06715912e-01, -4.38830943e-02, -2.36790549e-02, -1.37774382e-02,\n",
       "        7.85316354e-03,  3.53133180e-02,  2.51301879e-01,  4.52209315e-01,\n",
       "        3.75945346e+00])"
      ]
     },
     "execution_count": 135,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 排序后，正相关程度最高的系数排在最右边，负相关程度最高的系数排在最左边\n",
    "np.sort(lin_reg.coef_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* CRIM per capita crime rate by town： 城镇人均犯罪率\n",
    "* ZN proportion of residential land zoned for lots over 25,000 sq.ft：2.5万以上宗地住宅用地锌比例平方英尺.\n",
    "* INDUS, proportion of non-retail business acres per town：印度河占每个城镇非零售商业用地的比例\n",
    "* CHAS, Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)：是否靠近Charles河\n",
    "* NOX, nitric oxides concentration (parts per 10 million)：氮氧化物浓度（百万分之一）\n",
    "* RM, average number of rooms per dwelling：每间住宅的平均房间数\n",
    "* AGE, proportion of owner-occupied units built prior to 1940：1940年以前建造的自住单位的年龄比例\n",
    "* DIS, weighted distances to five Boston employment centres：到五个波士顿就业中心的加权距离\n",
    "* RAD, index of accessibility to radial highways：辐射状公路可达性RAD指数\n",
    "* TAX, full-value property-tax rate per \\$10,000：完税价房地产税率每万元\n",
    "* PTRATIO, pupil-teacher ratio by town：城镇师生比\n",
    "* B, 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town：B 1000（Bk-0.63）^2其中Bk是按城镇划分的黑人比例\n",
    "* LSTAT, % lower status of the population：人口地位低\n",
    "* MEDV, Median value of owner-occupied homes in $1000's：自有住房的MEDV中值（千美元）\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里的训练数据集反映的是波士顿房价和城市人均犯罪率、是否靠近河、住宅平均房间数等特征之间的关系。通过训练得到的回归算法的系数，如果参数大于0，表示随着该系数对应的那个特征的增加，房价会上涨，反之下降；如果系数小于0，表示随着系数对应的那个特征的增加，房价会下降，反之上涨。例如：<font color=red>城市人均犯罪率这个特征对应在回归算法中算得的系数为`-1.06715912e-01`，那么随着城市人均犯罪率的上升，房价会下降，这就是线性回归算法对数据具有可解释性。</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "270px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
